allHubs = hardwareMap.getAll(LynxModule.class);
-
- ElapsedTime timer = new ElapsedTime();
-
- telemetry.addData(">", "Press START to start tests");
- telemetry.addData(">", "Test results will update for each access method.");
- telemetry.update();
- waitForStart();
-
- // --------------------------------------------------------------------------------------
- // Run control loop using legacy encoder reads
- // In this mode, a single read is done for each encoder position, and a bulk read is done for each velocity read.
- // This is the worst case scenario.
- // This is the same as using LynxModule.BulkCachingMode.OFF
- // --------------------------------------------------------------------------------------
-
- displayCycleTimes("Test 1 of 3 (Wait for completion)");
-
- timer.reset();
- cycles = 0;
- while (opModeIsActive() && (cycles++ < TEST_CYCLES)) {
- e1 = m1.getCurrentPosition();
- e2 = m2.getCurrentPosition();
- e3 = m3.getCurrentPosition();
- e4 = m4.getCurrentPosition();
-
- v1 = m1.getVelocity();
- v2 = m2.getVelocity();
- v3 = m3.getVelocity();
- v4 = m4.getVelocity();
-
- // Put Control loop action code here.
-
- }
- // calculate the average cycle time.
- t1 = timer.milliseconds() / cycles;
- displayCycleTimes("Test 2 of 3 (Wait for completion)");
-
- // --------------------------------------------------------------------------------------
- // Run test cycles using AUTO cache mode
- // In this mode, only one bulk read is done per cycle, UNLESS you read a specific encoder/velocity item AGAIN in that cycle.
- // --------------------------------------------------------------------------------------
-
- // Important Step 3: Option A. Set all Expansion hubs to use the AUTO Bulk Caching mode
- for (LynxModule module : allHubs) {
- module.setBulkCachingMode(LynxModule.BulkCachingMode.AUTO);
- }
-
- timer.reset();
- cycles = 0;
- while (opModeIsActive() && (cycles++ < TEST_CYCLES)) {
- e1 = m1.getCurrentPosition(); // Uses 1 bulk-read for all 4 encoder/velocity reads,
- e2 = m2.getCurrentPosition(); // but don't do any `get` operations more than once per cycle.
- e3 = m3.getCurrentPosition();
- e4 = m4.getCurrentPosition();
-
- v1 = m1.getVelocity();
- v2 = m2.getVelocity();
- v3 = m3.getVelocity();
- v4 = m4.getVelocity();
-
- // Put Control loop action code here.
-
- }
- // calculate the average cycle time.
- t2 = timer.milliseconds() / cycles;
- displayCycleTimes("Test 3 of 3 (Wait for completion)");
-
- // --------------------------------------------------------------------------------------
- // Run test cycles using MANUAL cache mode
- // In this mode, only one block read is done each control cycle.
- // This is the MOST efficient method, but it does require that the cache is cleared manually each control cycle.
- // --------------------------------------------------------------------------------------
-
- // Important Step 3: Option B. Set all Expansion hubs to use the MANUAL Bulk Caching mode
- for (LynxModule module : allHubs) {
- module.setBulkCachingMode(LynxModule.BulkCachingMode.MANUAL);
- }
-
- timer.reset();
- cycles = 0;
- while (opModeIsActive() && (cycles++ < TEST_CYCLES)) {
-
- // Important Step 4: If you are using MANUAL mode, you must clear the BulkCache once per control cycle
- for (LynxModule module : allHubs) {
- module.clearBulkCache();
- }
-
- e1 = m1.getCurrentPosition(); // Uses 1 bulk-read to obtain ALL the motor data
- e2 = m2.getCurrentPosition(); // There is no penalty for doing more `get` operations in this cycle,
- e3 = m3.getCurrentPosition(); // but they will return the same data.
- e4 = m4.getCurrentPosition();
-
- v1 = m1.getVelocity();
- v2 = m2.getVelocity();
- v3 = m3.getVelocity();
- v4 = m4.getVelocity();
-
- // Put Control loop action code here.
-
- }
- // calculate the average cycle time.
- t3 = timer.milliseconds() / cycles;
- displayCycleTimes("Complete");
-
- // wait until op-mode is stopped by user, before clearing display.
- while (opModeIsActive()) ;
- }
-
- // Display three comparison times.
- void displayCycleTimes(String status) {
- telemetry.addData("Testing", status);
- telemetry.addData("Cache = OFF", "%5.1f mS/cycle", t1);
- telemetry.addData("Cache = AUTO", "%5.1f mS/cycle", t2);
- telemetry.addData("Cache = MANUAL", "%5.1f mS/cycle", t3);
- telemetry.update();
- }
-}
-
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptNullOp.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptNullOp.java
deleted file mode 100644
index 4a887bda..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptNullOp.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.OpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.util.ElapsedTime;
-
-/*
- * Demonstrates an empty iterative OpMode
- */
-@TeleOp(name = "Concept: NullOp", group = "Concept")
-@Disabled
-public class ConceptNullOp extends OpMode {
-
- private ElapsedTime runtime = new ElapsedTime();
-
- /**
- * This method will be called once, when the INIT button is pressed.
- */
- @Override
- public void init() {
- telemetry.addData("Status", "Initialized");
- }
-
- /**
- * This method will be called repeatedly during the period between when
- * the INIT button is pressed and when the START button is pressed (or the
- * OpMode is stopped).
- */
- @Override
- public void init_loop() {
- }
-
- /**
- * This method will be called once, when the START button is pressed.
- */
- @Override
- public void start() {
- runtime.reset();
- }
-
- /**
- * This method will be called repeatedly during the period between when
- * the START button is pressed and when the OpMode is stopped.
- */
- @Override
- public void loop() {
- telemetry.addData("Status", "Run Time: " + runtime.toString());
- }
-
- /**
- * This method will be called once, when this OpMode is stopped.
- *
- * Your ability to control hardware from this method will be limited.
- */
- @Override
- public void stop() {
-
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRampMotorSpeed.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRampMotorSpeed.java
deleted file mode 100644
index 6e0be376..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRampMotorSpeed.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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 com.qualcomm.robotcore.hardware.DcMotor;
-
-/*
- * This OpMode ramps a single motor speed up and down repeatedly until Stop is pressed.
- * The code is structured as a LinearOpMode
- *
- * This code assumes a DC motor configured with the name "left_drive" as is found on a Robot.
- *
- * INCREMENT sets how much to increase/decrease the power each cycle
- * CYCLE_MS sets the update period.
- *
- * 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: Ramp Motor Speed", group = "Concept")
-@Disabled
-public class ConceptRampMotorSpeed extends LinearOpMode {
-
- static final double INCREMENT = 0.01; // amount to ramp motor each CYCLE_MS cycle
- static final int CYCLE_MS = 50; // period of each cycle
- static final double MAX_FWD = 1.0; // Maximum FWD power applied to motor
- static final double MAX_REV = -1.0; // Maximum REV power applied to motor
-
- // Define class members
- DcMotor motor;
- double power = 0;
- boolean rampUp = true;
-
-
- @Override
- public void runOpMode() {
-
- // Connect to motor (Assume standard left wheel)
- // Change the text in quotes to match any motor name on your robot.
- motor = hardwareMap.get(DcMotor.class, "left_drive");
-
- // Wait for the start button
- telemetry.addData(">", "Press Start to run Motors." );
- telemetry.update();
- waitForStart();
-
- // Ramp motor speeds till stop pressed.
- while(opModeIsActive()) {
-
- // Ramp the motors, according to the rampUp variable.
- if (rampUp) {
- // Keep stepping up until we hit the max value.
- power += INCREMENT ;
- if (power >= MAX_FWD ) {
- power = MAX_FWD;
- rampUp = !rampUp; // Switch ramp direction
- }
- }
- else {
- // Keep stepping down until we hit the min value.
- power -= INCREMENT ;
- if (power <= MAX_REV ) {
- power = MAX_REV;
- rampUp = !rampUp; // Switch ramp direction
- }
- }
-
- // Display the current value
- telemetry.addData("Motor Power", "%5.2f", power);
- telemetry.addData(">", "Press Stop to end test." );
- telemetry.update();
-
- // Set the motor to the new power and pause;
- motor.setPower(power);
- sleep(CYCLE_MS);
- idle();
- }
-
- // Turn off motor and signal done;
- motor.setPower(0);
- telemetry.addData(">", "Done");
- telemetry.update();
-
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRevLED.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRevLED.java
deleted file mode 100644
index 9c168d50..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRevLED.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- 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();
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRevSPARKMini.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRevSPARKMini.java
deleted file mode 100644
index 798d6893..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRevSPARKMini.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Copyright (c) 2018 FIRST. 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 com.qualcomm.robotcore.hardware.DcMotorSimple;
-import com.qualcomm.robotcore.util.ElapsedTime;
-import com.qualcomm.robotcore.util.Range;
-
-
-/*
- * This OpMode demonstrates a POV Drive system, with commented-out code for a Tank Drive system,
- * 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'
- * and name them 'left_drive' and 'right_drive'.
- *
- * 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="REV SPARKmini Simple Drive Example", group="Concept")
-@Disabled
-public class ConceptRevSPARKMini extends LinearOpMode {
-
- // Declare OpMode members.
- private ElapsedTime runtime = new ElapsedTime();
- private DcMotorSimple leftDrive = null;
- private DcMotorSimple rightDrive = null;
-
- @Override
- public void runOpMode() {
- telemetry.addData("Status", "Initialized");
- telemetry.update();
-
- // Initialize the hardware variables. Note that the strings used here as parameters
- // to 'get' must correspond to the names assigned during robot configuration.
- leftDrive = hardwareMap.get(DcMotorSimple.class, "left_drive");
- rightDrive = hardwareMap.get(DcMotorSimple.class, "right_drive");
-
- // Most robots need the motor on one side to be reversed to drive forward
- // Reverse the motor that runs backward when connected directly to the battery
- leftDrive.setDirection(DcMotorSimple.Direction.FORWARD);
- rightDrive.setDirection(DcMotorSimple.Direction.REVERSE);
-
- // Wait for the game to start (driver presses START)
- waitForStart();
- runtime.reset();
-
- // run until the end of the match (driver presses STOP)
- while (opModeIsActive()) {
-
- // Setup a variable for each drive wheel to save power level for telemetry
- double leftPower;
- double rightPower;
-
- // Choose to drive using either Tank Mode, or POV Mode
- // Comment out the method that's not used. The default below is POV.
-
- // POV Mode uses left stick to go forward, and right stick to turn.
- // - This uses basic math to combine motions and is easier to drive straight.
- double drive = -gamepad1.left_stick_y;
- double turn = gamepad1.right_stick_x;
- leftPower = Range.clip(drive + turn, -1.0, 1.0) ;
- rightPower = Range.clip(drive - turn, -1.0, 1.0) ;
-
- // Tank Mode uses one stick to control each wheel.
- // - This requires no math, but it is hard to drive forward slowly and keep straight.
- // leftPower = -gamepad1.left_stick_y ;
- // rightPower = -gamepad1.right_stick_y ;
-
- // Send calculated power to wheels
- leftDrive.setPower(leftPower);
- rightDrive.setPower(rightPower);
-
- // Show the elapsed game time and wheel power.
- telemetry.addData("Status", "Run Time: " + runtime.toString());
- telemetry.addData("Motors", "left (%.2f), right (%.2f)", leftPower, rightPower);
- telemetry.update();
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptScanServo.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptScanServo.java
deleted file mode 100644
index 2b8ad332..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptScanServo.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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 com.qualcomm.robotcore.hardware.Servo;
-
-/*
- * This OpMode scans a single servo back and forward until Stop is pressed.
- * The code is structured as a LinearOpMode
- * INCREMENT sets how much to increase/decrease the servo position each cycle
- * CYCLE_MS sets the update period.
- *
- * This code assumes a Servo configured with the name "left_hand" as is found on a Robot.
- *
- * NOTE: When any servo position is set, ALL attached servos are activated, so ensure that any other
- * connected servos are able to move freely before running this test.
- *
- * 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: Scan Servo", group = "Concept")
-@Disabled
-public class ConceptScanServo extends LinearOpMode {
-
- static final double INCREMENT = 0.01; // amount to slew servo each CYCLE_MS cycle
- static final int CYCLE_MS = 50; // period of each cycle
- static final double MAX_POS = 1.0; // Maximum rotational position
- static final double MIN_POS = 0.0; // Minimum rotational position
-
- // Define class members
- Servo servo;
- double position = (MAX_POS - MIN_POS) / 2; // Start at halfway position
- boolean rampUp = true;
-
-
- @Override
- public void runOpMode() {
-
- // Connect to servo (Assume Robot Left Hand)
- // Change the text in quotes to match any servo name on your robot.
- servo = hardwareMap.get(Servo.class, "left_hand");
-
- // Wait for the start button
- telemetry.addData(">", "Press Start to scan Servo." );
- telemetry.update();
- waitForStart();
-
-
- // Scan servo till stop pressed.
- while(opModeIsActive()){
-
- // slew the servo, according to the rampUp (direction) variable.
- if (rampUp) {
- // Keep stepping up until we hit the max value.
- position += INCREMENT ;
- if (position >= MAX_POS ) {
- position = MAX_POS;
- rampUp = !rampUp; // Switch ramp direction
- }
- }
- else {
- // Keep stepping down until we hit the min value.
- position -= INCREMENT ;
- if (position <= MIN_POS ) {
- position = MIN_POS;
- rampUp = !rampUp; // Switch ramp direction
- }
- }
-
- // Display the current value
- telemetry.addData("Servo Position", "%5.2f", position);
- telemetry.addData(">", "Press Stop to end test." );
- telemetry.update();
-
- // Set the servo to the new position and pause;
- servo.setPosition(position);
- sleep(CYCLE_MS);
- idle();
- }
-
- // Signal done;
- telemetry.addData(">", "Done");
- telemetry.update();
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptSoundsASJava.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptSoundsASJava.java
deleted file mode 100644
index 1ceaa17d..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptSoundsASJava.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/* Copyright (c) 2018 FIRST. 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.ftccommon.SoundPlayer;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-
-/*
- * This OpMode demonstrates how to play simple sounds on both the RC and DS phones.
- * It illustrates how to build sounds into your application as a resource.
- * This technique is best suited for use with Android Studio since it assumes you will be creating a new application
- *
- * If you are using OnBotJava, please see the ConceptSoundsOnBotJava sample
- *
- * 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
- *
- * Operation:
- *
- * Gamepad X & B buttons are used to trigger sounds in this example, but any event can be used.
- * Note: Time should be allowed for sounds to complete before playing other sounds.
- *
- * For sound files to be used as a compiled-in resource, they need to be located in a folder called "raw" under your "res" (resources) folder.
- * You can create your own "raw" folder from scratch, or you can copy the one from the FtcRobotController module.
- *
- * Android Studio coders will ultimately need a folder in your path as follows:
- * /TeamCode/src/main/res/raw
- *
- * Copy any .wav files you want to play into this folder.
- * Make sure that your files ONLY use lower-case characters, and have no spaces or special characters other than underscore.
- *
- * The name you give your .wav files will become the resource ID for these sounds.
- * eg: gold.wav becomes R.raw.gold
- *
- * If you wish to use the sounds provided for this sample, they are located in:
- * /FtcRobotController/src/main/res/raw
- * You can copy and paste the entire 'raw' folder using Android Studio.
- *
- */
-
-@TeleOp(name="Concept: Sound Resources", group="Concept")
-@Disabled
-public class ConceptSoundsASJava extends LinearOpMode {
-
- // Declare OpMode members.
- private boolean goldFound; // Sound file present flags
- private boolean silverFound;
-
- private boolean isX = false; // Gamepad button state variables
- private boolean isB = false;
-
- private boolean wasX = false; // Gamepad button history variables
- private boolean WasB = false;
-
- @Override
- public void runOpMode() {
-
- // Determine Resource IDs for sounds built into the RC application.
- int silverSoundID = hardwareMap.appContext.getResources().getIdentifier("silver", "raw", hardwareMap.appContext.getPackageName());
- int goldSoundID = hardwareMap.appContext.getResources().getIdentifier("gold", "raw", hardwareMap.appContext.getPackageName());
-
- // Determine if sound resources are found.
- // Note: Preloading is NOT required, but it's a good way to verify all your sounds are available before you run.
- if (goldSoundID != 0)
- goldFound = SoundPlayer.getInstance().preload(hardwareMap.appContext, goldSoundID);
-
- if (silverSoundID != 0)
- silverFound = SoundPlayer.getInstance().preload(hardwareMap.appContext, silverSoundID);
-
- // Display sound status
- 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" );
-
- // Wait for the game to start (driver presses START)
- telemetry.addData(">", "Press Start to continue");
- telemetry.update();
- waitForStart();
-
- telemetry.addData(">", "Press X, B to play sounds.");
- telemetry.update();
-
- // run until the end of the match (driver presses STOP)
- while (opModeIsActive()) {
-
- // say Silver each time gamepad X is pressed (This sound is a resource)
- if (silverFound && (isX = gamepad1.x) && !wasX) {
- SoundPlayer.getInstance().startPlaying(hardwareMap.appContext, silverSoundID);
- telemetry.addData("Playing", "Resource Silver");
- telemetry.update();
- }
-
- // say Gold each time gamepad B is pressed (This sound is a resource)
- if (goldFound && (isB = gamepad1.b) && !WasB) {
- SoundPlayer.getInstance().startPlaying(hardwareMap.appContext, goldSoundID);
- telemetry.addData("Playing", "Resource Gold");
- telemetry.update();
- }
-
- // Save last button states
- wasX = isX;
- WasB = isB;
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptSoundsOnBotJava.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptSoundsOnBotJava.java
deleted file mode 100644
index fbb7416c..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptSoundsOnBotJava.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/* Copyright (c) 2018 FIRST. 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.ftccommon.SoundPlayer;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-
-import java.io.File;
-
-/*
- * This OpMode demonstrates how to play simple sounds on both the RC and DS phones.
- * It illustrates how to play sound files that have been copied to the RC Phone
- * This technique is best suited for use with OnBotJava since it does not require the app to be modified.
- *
- * Operation:
- *
- * Gamepad X & B buttons are used to trigger sounds in this example, but any event can be used.
- * Note: Time should be allowed for sounds to complete before playing other sounds.
- *
- * To play a new sound, you will need to copy the .wav files to the phone, and then provide the full path to them as part of your OpMode.
- * This is done in this sample for the two sound files. silver.wav and gold.wav
- *
- * You can put the files in a variety of soundPaths, but we recommend you put them in the /FIRST/blocks/sounds folder.
- * Your OpModes will have guaranteed access to this folder, and you can transfer files into this folder using the BLOCKS web page.
- * -- There is a link called "sounds" on the right hand side of the color bar on the BLOCKS page that can be used to send sound files to this folder by default.
- * Or you can use Windows File Manager, or ADB to transfer the sound files
- *
- * To get full use of THIS sample, you will need to copy two sound file called silver.wav and gold.wav to /FIRST/blocks/sounds on the RC phone.
- * They can be located here:
- * https://github.com/ftctechnh/ftc_app/tree/master/FtcRobotController/src/main/res/raw/gold.wav
- * https://github.com/ftctechnh/ftc_app/tree/master/FtcRobotController/src/main/res/raw/silver.wav
- */
-
-@TeleOp(name="Concept: Sound Files", group="Concept")
-@Disabled
-public class ConceptSoundsOnBotJava extends LinearOpMode {
-
- // Point to sound files on the phone's drive
- private String soundPath = "/FIRST/blocks/sounds";
- private File goldFile = new File("/sdcard" + soundPath + "/gold.wav");
- private File silverFile = new File("/sdcard" + soundPath + "/silver.wav");
-
- // Declare OpMode members.
- private boolean isX = false; // Gamepad button state variables
- private boolean isB = false;
-
- private boolean wasX = false; // Gamepad button history variables
- private boolean WasB = false;
-
- @Override
- public void runOpMode() {
-
- // Make sure that the sound files exist on the phone
- boolean goldFound = goldFile.exists();
- boolean silverFound = silverFile.exists();
-
- // Display sound status
- telemetry.addData("gold sound", goldFound ? "Found" : "NOT Found \nCopy gold.wav to " + soundPath );
- telemetry.addData("silver sound", silverFound ? "Found" : "NOT Found \nCopy silver.wav to " + soundPath );
-
- // Wait for the game to start (driver presses PLAY)
- telemetry.addData(">", "Press Start to continue");
- telemetry.update();
- waitForStart();
-
- telemetry.addData(">", "Press X or B to play sounds.");
- telemetry.update();
-
- // run until the end of the match (driver presses STOP)
- while (opModeIsActive()) {
-
- // say Silver each time gamepad X is pressed (This sound is a resource)
- if (silverFound && (isX = gamepad1.x) && !wasX) {
- SoundPlayer.getInstance().startPlaying(hardwareMap.appContext, silverFile);
- telemetry.addData("Playing", "Silver File");
- telemetry.update();
- }
-
- // say Gold each time gamepad B is pressed (This sound is a resource)
- if (goldFound && (isB = gamepad1.b) && !WasB) {
- SoundPlayer.getInstance().startPlaying(hardwareMap.appContext, goldFile);
- telemetry.addData("Playing", "Gold File");
- telemetry.update();
- }
-
- // Save last button states
- wasX = isX;
- WasB = isB;
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptSoundsSKYSTONE.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptSoundsSKYSTONE.java
deleted file mode 100644
index 983e434f..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptSoundsSKYSTONE.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/* Copyright (c) 2018 FIRST. 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 android.content.Context;
-import com.qualcomm.ftccommon.SoundPlayer;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-
-/*
- * This OpMode demonstrates how to play one of the several SKYSTONE/Star Wars sounds loaded into the SDK.
- * It does this by creating a simple "chooser" controlled by the gamepad Up Down buttons.
- * This code also prevents sounds from stacking up by setting a "playing" flag, which is cleared when the sound finishes playing.
- *
- * 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
- *
- * Operation:
- * Use the DPAD to change the selected sound, and the Right Bumper to play it.
- */
-
-@TeleOp(name="SKYSTONE Sounds", group="Concept")
-@Disabled
-public class ConceptSoundsSKYSTONE extends LinearOpMode {
-
- // List of available sound resources
- String sounds[] = {"ss_alarm", "ss_bb8_down", "ss_bb8_up", "ss_darth_vader", "ss_fly_by",
- "ss_mf_fail", "ss_laser", "ss_laser_burst", "ss_light_saber", "ss_light_saber_long", "ss_light_saber_short",
- "ss_light_speed", "ss_mine", "ss_power_up", "ss_r2d2_up", "ss_roger_roger", "ss_siren", "ss_wookie" };
- boolean soundPlaying = false;
-
- @Override
- public void runOpMode() {
-
- // Variables for choosing from the available sounds
- int soundIndex = 0;
- int soundID = -1;
- boolean was_dpad_up = false;
- boolean was_dpad_down = false;
-
- Context myApp = hardwareMap.appContext;
-
- // create a sound parameter that holds the desired player parameters.
- SoundPlayer.PlaySoundParams params = new SoundPlayer.PlaySoundParams();
- params.loopControl = 0;
- params.waitForNonLoopingSoundsToFinish = true;
-
- // In this sample, we will skip waiting for the user to press play, and start displaying sound choices right away
- while (!isStopRequested()) {
-
- // Look for DPAD presses to change the selection
- if (gamepad1.dpad_down && !was_dpad_down) {
- // Go to next sound (with list wrap) and display it
- soundIndex = (soundIndex + 1) % sounds.length;
- }
-
- if (gamepad1.dpad_up && !was_dpad_up) {
- // Go to previous sound (with list wrap) and display it
- soundIndex = (soundIndex + sounds.length - 1) % sounds.length;
- }
-
- // Look for trigger to see if we should play sound
- // Only start a new sound if we are currently not playing one.
- if (gamepad1.right_bumper && !soundPlaying) {
-
- // Determine Resource IDs for the sounds you want to play, and make sure it's valid.
- if ((soundID = myApp.getResources().getIdentifier(sounds[soundIndex], "raw", myApp.getPackageName())) != 0){
-
- // Signal that the sound is now playing.
- soundPlaying = true;
-
- // Start playing, and also Create a callback that will clear the playing flag when the sound is complete.
- SoundPlayer.getInstance().startPlaying(myApp, soundID, params, null,
- new Runnable() {
- public void run() {
- soundPlaying = false;
- }} );
- }
- }
-
- // Remember the last state of the dpad to detect changes.
- was_dpad_up = gamepad1.dpad_up;
- was_dpad_down = gamepad1.dpad_down;
-
- // Display the current sound choice, and the playing status.
- telemetry.addData("", "Use DPAD up/down to choose sound.");
- telemetry.addData("", "Press Right Bumper to play sound.");
- telemetry.addData("", "");
- telemetry.addData("Sound >", sounds[soundIndex]);
- telemetry.addData("Status >", soundPlaying ? "Playing" : "Stopped");
- telemetry.update();
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptTelemetry.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptTelemetry.java
deleted file mode 100644
index f2c60970..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptTelemetry.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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 com.qualcomm.robotcore.hardware.VoltageSensor;
-import com.qualcomm.robotcore.util.ElapsedTime;
-import org.firstinspires.ftc.robotcore.external.Func;
-import org.firstinspires.ftc.robotcore.external.Telemetry;
-
-/*
- * This OpMode illustrates various ways in which telemetry can be
- * transmitted from the robot controller to the driver station. The sample illustrates
- * numeric and text data, formatted output, and optimized evaluation of expensive-to-acquire
- * information. The telemetry log is illustrated by scrolling a poem
- * to the driver station.
- *
- * Also see the Telemetry javadocs.
- */
-@TeleOp(name = "Concept: Telemetry", group = "Concept")
-@Disabled
-public class ConceptTelemetry extends LinearOpMode {
- /** Keeps track of the line of the poem which is to be emitted next */
- int poemLine = 0;
-
- /** Keeps track of how long it's been since we last emitted a line of poetry */
- ElapsedTime poemElapsed = new ElapsedTime();
-
- static final String[] poem = new String[] {
-
- "Mary had a little lamb,",
- "His fleece was white as snow,",
- "And everywhere that Mary went,",
- "The lamb was sure to go.",
- "",
- "He followed her to school one day,",
- "Which was against the rule,",
- "It made the children laugh and play",
- "To see a lamb at school.",
- "",
- "And so the teacher turned it out,",
- "But still it lingered near,",
- "And waited patiently about,",
- "Till Mary did appear.",
- "",
- "\"Why does the lamb love Mary so?\"",
- "The eager children cry.",
- "\"Why, Mary loves the lamb, you know,\"",
- "The teacher did reply.",
- "",
- ""
- };
-
- @Override public void runOpMode() {
-
- /* we keep track of how long it's been since the OpMode was started, just
- * to have some interesting data to show */
- ElapsedTime opmodeRunTime = new ElapsedTime();
-
- // We show the log in oldest-to-newest order, as that's better for poetry
- telemetry.log().setDisplayOrder(Telemetry.Log.DisplayOrder.OLDEST_FIRST);
- // We can control the number of lines shown in the log
- telemetry.log().setCapacity(6);
- // The interval between lines of poetry, in seconds
- double sPoemInterval = 0.6;
-
- /*
- * Wait until we've been given the ok to go. For something to do, we emit the
- * elapsed time as we sit here and wait. If we didn't want to do anything while
- * we waited, we would just call waitForStart().
- */
- while (!isStarted()) {
- telemetry.addData("time", "%.1f seconds", opmodeRunTime.seconds());
- telemetry.update();
- idle();
- }
-
- // Ok, we've been given the ok to go
-
- /*
- * As an illustration, the first line on our telemetry display will display the battery voltage.
- * The idea here is that it's expensive to compute the voltage (at least for purposes of illustration)
- * so you don't want to do it unless the data is _actually_ going to make it to the
- * driver station (recall that telemetry transmission is throttled to reduce bandwidth use.
- * Note that getBatteryVoltage() below returns 'Infinity' if there's no voltage sensor attached.
- *
- * @see Telemetry#getMsTransmissionInterval()
- */
- telemetry.addData("voltage", "%.1f volts", new Func() {
- @Override public Double value() {
- return getBatteryVoltage();
- }
- });
-
- // Reset to keep some timing stats for the post-'start' part of the OpMode
- opmodeRunTime.reset();
- int loopCount = 1;
-
- // Go go gadget robot!
- while (opModeIsActive()) {
-
- // Emit poetry if it's been a while
- if (poemElapsed.seconds() > sPoemInterval) {
- emitPoemLine();
- }
-
- // As an illustration, show some loop timing information
- telemetry.addData("loop count", loopCount);
- telemetry.addData("ms/loop", "%.3f ms", opmodeRunTime.milliseconds() / loopCount);
-
- // Show joystick information as some other illustrative data
- telemetry.addLine("left joystick | ")
- .addData("x", gamepad1.left_stick_x)
- .addData("y", gamepad1.left_stick_y);
- telemetry.addLine("right joystick | ")
- .addData("x", gamepad1.right_stick_x)
- .addData("y", gamepad1.right_stick_y);
-
- /*
- * Transmit the telemetry to the driver station, subject to throttling.
- * See the documentation for Telemetry.getMsTransmissionInterval() for more information.
- */
- telemetry.update();
-
- // Update loop info
- loopCount++;
- }
- }
-
- // emits a line of poetry to the telemetry log
- void emitPoemLine() {
- telemetry.log().add(poem[poemLine]);
- poemLine = (poemLine+1) % poem.length;
- poemElapsed.reset();
- }
-
- // Computes the current battery voltage
- double getBatteryVoltage() {
- double result = Double.POSITIVE_INFINITY;
- for (VoltageSensor sensor : hardwareMap.voltageSensor) {
- double voltage = sensor.getVoltage();
- if (voltage > 0) {
- result = Math.min(result, voltage);
- }
- }
- return result;
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVisionColorLocator.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVisionColorLocator.java
deleted file mode 100644
index 987694db..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVisionColorLocator.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (c) 2024 Phil Malone
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.firstinspires.ftc.robotcontroller.external.samples;
-
-import android.util.Size;
-
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.util.SortOrder;
-
-import org.firstinspires.ftc.robotcore.external.Telemetry;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName;
-import org.firstinspires.ftc.vision.VisionPortal;
-import org.firstinspires.ftc.vision.opencv.ColorBlobLocatorProcessor;
-import org.firstinspires.ftc.vision.opencv.ColorRange;
-import org.firstinspires.ftc.vision.opencv.ImageRegion;
-import org.opencv.core.RotatedRect;
-
-import java.util.List;
-
-/*
- * This OpMode illustrates how to use a video source (camera) to locate specifically colored regions
- *
- * Unlike a "color sensor" which determines the color of an object in the field of view, this "color locator"
- * will search the Region Of Interest (ROI) in a camera image, and find any "blobs" of color that match the requested color range.
- * These blobs can be further filtered and sorted to find the one most likely to be the item the user is looking for.
- *
- * To perform this function, a VisionPortal runs a ColorBlobLocatorProcessor process.
- * The ColorBlobLocatorProcessor process is created first, and then the VisionPortal is built to use this process.
- * The ColorBlobLocatorProcessor analyses the ROI and locates pixels that match the ColorRange to form a "mask".
- * The matching pixels are then collected into contiguous "blobs" of pixels. The outer boundaries of these blobs are called its "contour".
- * For each blob, the process then creates the smallest possible rectangle "boxFit" that will fully encase the contour.
- * The user can then call getBlobs() to retrieve the list of Blobs, where each Blob contains the contour and the boxFit data.
- * Note: The default sort order for Blobs is ContourArea, in descending order, so the biggest contours are listed first.
- *
- * To aid the user, a colored boxFit rectangle is drawn on the camera preview to show the location of each Blob
- * The original Blob contour can also be added to the preview. This is helpful when configuring the ColorBlobLocatorProcessor parameters.
- *
- * 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
- */
-
-@Disabled
-@TeleOp(name = "Concept: Vision Color-Locator", group = "Concept")
-public class ConceptVisionColorLocator extends LinearOpMode
-{
- @Override
- public void runOpMode()
- {
- /* Build a "Color Locator" vision processor based on the ColorBlobLocatorProcessor class.
- * - Specify the color range you are looking for. You can use a predefined color, or create you own color range
- * .setTargetColorRange(ColorRange.BLUE) // use a predefined color match
- * Available predefined colors are: RED, BLUE YELLOW GREEN
- * .setTargetColorRange(new ColorRange(ColorSpace.YCrCb, // or define your own color match
- * new Scalar( 32, 176, 0),
- * new Scalar(255, 255, 132)))
- *
- * - Focus the color locator by defining a RegionOfInterest (ROI) which you want to search.
- * This can be the entire frame, or a sub-region defined using:
- * 1) standard image coordinates or 2) a normalized +/- 1.0 coordinate system.
- * Use one form of the ImageRegion class to define the ROI.
- * ImageRegion.entireFrame()
- * ImageRegion.asImageCoordinates(50, 50, 150, 150) 100x100 pixel square near the upper left corner
- * ImageRegion.asUnityCenterCoordinates(-0.5, 0.5, 0.5, -0.5) 50% width/height square centered on screen
- *
- * - Define which contours are included.
- * You can get ALL the contours, or you can skip any contours that are completely inside another contour.
- * .setContourMode(ColorBlobLocatorProcessor.ContourMode.ALL_FLATTENED_HIERARCHY) // return all contours
- * .setContourMode(ColorBlobLocatorProcessor.ContourMode.EXTERNAL_ONLY) // exclude contours inside other contours
- * note: EXTERNAL_ONLY helps to avoid bright reflection spots from breaking up areas of solid color.
- *
- * - turn the display of contours ON or OFF. Turning this on helps debugging but takes up valuable CPU time.
- * .setDrawContours(true)
- *
- * - include any pre-processing of the image or mask before looking for Blobs.
- * There are some extra processing you can include to improve the formation of blobs. Using these features requires
- * an understanding of how they may effect the final blobs. The "pixels" argument sets the NxN kernel size.
- * .setBlurSize(int pixels) Blurring an image helps to provide a smooth color transition between objects, and smoother contours.
- * The higher the number of pixels, the more blurred the image becomes.
- * Note: Even "pixels" values will be incremented to satisfy the "odd number" requirement.
- * Blurring too much may hide smaller features. A "pixels" size of 5 is good for a 320x240 image.
- * .setErodeSize(int pixels) Erosion removes floating pixels and thin lines so that only substantive objects remain.
- * Erosion can grow holes inside regions, and also shrink objects.
- * "pixels" in the range of 2-4 are suitable for low res images.
- * .setDilateSize(int pixels) Dilation makes objects more visible by filling in small holes, making lines appear thicker,
- * and making filled shapes appear larger. Dilation is useful for joining broken parts of an
- * object, such as when removing noise from an image.
- * "pixels" in the range of 2-4 are suitable for low res images.
- */
- ColorBlobLocatorProcessor colorLocator = new ColorBlobLocatorProcessor.Builder()
- .setTargetColorRange(ColorRange.BLUE) // use a predefined color match
- .setContourMode(ColorBlobLocatorProcessor.ContourMode.EXTERNAL_ONLY) // exclude blobs inside blobs
- .setRoi(ImageRegion.asUnityCenterCoordinates(-0.5, 0.5, 0.5, -0.5)) // search central 1/4 of camera view
- .setDrawContours(true) // Show contours on the Stream Preview
- .setBlurSize(5) // Smooth the transitions between different colors in image
- .build();
-
- /*
- * Build a vision portal to run the Color Locator process.
- *
- * - Add the colorLocator process created above.
- * - Set the desired video resolution.
- * Since a high resolution will not improve this process, choose a lower resolution that is
- * supported by your camera. This will improve overall performance and reduce latency.
- * - Choose your video source. This may be
- * .setCamera(hardwareMap.get(WebcamName.class, "Webcam 1")) ..... for a webcam
- * or
- * .setCamera(BuiltinCameraDirection.BACK) ... for a Phone Camera
- */
- VisionPortal portal = new VisionPortal.Builder()
- .addProcessor(colorLocator)
- .setCameraResolution(new Size(320, 240))
- .setCamera(hardwareMap.get(WebcamName.class, "Webcam 1"))
- .build();
-
- telemetry.setMsTransmissionInterval(50); // Speed up telemetry updates, Just use for debugging.
- telemetry.setDisplayFormat(Telemetry.DisplayFormat.MONOSPACE);
-
- // WARNING: To be able to view the stream preview on the Driver Station, this code runs in INIT mode.
- while (opModeIsActive() || opModeInInit())
- {
- telemetry.addData("preview on/off", "... Camera Stream\n");
-
- // Read the current list
- List blobs = colorLocator.getBlobs();
-
- /*
- * The list of Blobs can be filtered to remove unwanted Blobs.
- * Note: All contours will be still displayed on the Stream Preview, but only those that satisfy the filter
- * conditions will remain in the current list of "blobs". Multiple filters may be used.
- *
- * Use any of the following filters.
- *
- * ColorBlobLocatorProcessor.Util.filterByArea(minArea, maxArea, blobs);
- * A Blob's area is the number of pixels contained within the Contour. Filter out any that are too big or small.
- * Start with a large range and then refine the range based on the likely size of the desired object in the viewfinder.
- *
- * ColorBlobLocatorProcessor.Util.filterByDensity(minDensity, maxDensity, blobs);
- * A blob's density is an indication of how "full" the contour is.
- * If you put a rubber band around the contour you would get the "Convex Hull" of the contour.
- * The density is the ratio of Contour-area to Convex Hull-area.
- *
- * ColorBlobLocatorProcessor.Util.filterByAspectRatio(minAspect, maxAspect, blobs);
- * A blob's Aspect ratio is the ratio of boxFit long side to short side.
- * A perfect Square has an aspect ratio of 1. All others are > 1
- */
- ColorBlobLocatorProcessor.Util.filterByArea(50, 20000, blobs); // filter out very small blobs.
-
- /*
- * The list of Blobs can be sorted using the same Blob attributes as listed above.
- * No more than one sort call should be made. Sorting can use ascending or descending order.
- * ColorBlobLocatorProcessor.Util.sortByArea(SortOrder.DESCENDING, blobs); // Default
- * ColorBlobLocatorProcessor.Util.sortByDensity(SortOrder.DESCENDING, blobs);
- * ColorBlobLocatorProcessor.Util.sortByAspectRatio(SortOrder.DESCENDING, blobs);
- */
-
- telemetry.addLine(" Area Density Aspect Center");
-
- // Display the size (area) and center location for each Blob.
- for(ColorBlobLocatorProcessor.Blob b : blobs)
- {
- RotatedRect boxFit = b.getBoxFit();
- telemetry.addLine(String.format("%5d %4.2f %5.2f (%3d,%3d)",
- b.getContourArea(), b.getDensity(), b.getAspectRatio(), (int) boxFit.center.x, (int) boxFit.center.y));
- }
-
- telemetry.update();
- sleep(50);
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVisionColorSensor.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVisionColorSensor.java
deleted file mode 100644
index 6be2bc4e..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVisionColorSensor.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (c) 2024 Phil Malone
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.firstinspires.ftc.robotcontroller.external.samples;
-
-import android.graphics.Color;
-import android.util.Size;
-
-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.WebcamName;
-import org.firstinspires.ftc.vision.VisionPortal;
-import org.firstinspires.ftc.vision.opencv.ImageRegion;
-import org.firstinspires.ftc.vision.opencv.PredominantColorProcessor;
-
-/*
- * This OpMode illustrates how to use a video source (camera) as a color sensor
- *
- * A "color sensor" will typically determine the color of the object that it is pointed at.
- *
- * This sample performs the same function, except it uses a video camera to inspect an object or scene.
- * The user may choose to inspect all, or just a Region of Interest (ROI), of the active camera view.
- * The user must also provide a list of "acceptable colors" (Swatches) from which the closest matching color will be selected.
- *
- * To perform this function, a VisionPortal runs a PredominantColorProcessor process.
- * The PredominantColorProcessor process is created first, and then the VisionPortal is built to use this process.
- * The PredominantColorProcessor analyses the ROI and splits the colored pixels into several color-clusters.
- * The largest of these clusters is then considered to be the "Predominant Color"
- * The process then matches the Predominant Color with the closest Swatch and returns that match.
- *
- * To aid the user, a colored rectangle is drawn on the camera preview to show the RegionOfInterest,
- * The Predominant Color is used to paint the rectangle border, so the user can verify that the color is reasonable.
- *
- * 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
- */
-
-@Disabled
-@TeleOp(name = "Concept: Vision Color-Sensor", group = "Concept")
-public class ConceptVisionColorSensor extends LinearOpMode
-{
- @Override
- public void runOpMode()
- {
- /* Build a "Color Sensor" vision processor based on the PredominantColorProcessor class.
- *
- * - Focus the color sensor by defining a RegionOfInterest (ROI) which you want to inspect.
- * This can be the entire frame, or a sub-region defined using:
- * 1) standard image coordinates or 2) a normalized +/- 1.0 coordinate system.
- * Use one form of the ImageRegion class to define the ROI.
- * ImageRegion.entireFrame()
- * ImageRegion.asImageCoordinates(50, 50, 150, 150) 100x100 pixel square near the upper left corner
- * ImageRegion.asUnityCenterCoordinates(-0.1, 0.1, 0.1, -0.1) 10% width/height square centered on screen
- *
- * - Set the list of "acceptable" color swatches (matches).
- * Only colors that you assign here will be returned.
- * If you know the sensor will be pointing to one of a few specific colors, enter them here.
- * Or, if the sensor may be pointed randomly, provide some additional colors that may match the surrounding.
- * Possible choices are:
- * RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, PURPLE, MAGENTA, BLACK, WHITE;
- *
- * Note that in the example shown below, only some of the available colors are included.
- * This will force any other colored region into one of these colors.
- * eg: Green may be reported as YELLOW, as this may be the "closest" match.
- */
- PredominantColorProcessor colorSensor = new PredominantColorProcessor.Builder()
- .setRoi(ImageRegion.asUnityCenterCoordinates(-0.1, 0.1, 0.1, -0.1))
- .setSwatches(
- PredominantColorProcessor.Swatch.RED,
- PredominantColorProcessor.Swatch.BLUE,
- PredominantColorProcessor.Swatch.YELLOW,
- PredominantColorProcessor.Swatch.BLACK,
- PredominantColorProcessor.Swatch.WHITE)
- .build();
-
- /*
- * Build a vision portal to run the Color Sensor process.
- *
- * - Add the colorSensor process created above.
- * - Set the desired video resolution.
- * Since a high resolution will not improve this process, choose a lower resolution that is
- * supported by your camera. This will improve overall performance and reduce latency.
- * - Choose your video source. This may be
- * .setCamera(hardwareMap.get(WebcamName.class, "Webcam 1")) ..... for a webcam
- * or
- * .setCamera(BuiltinCameraDirection.BACK) ... for a Phone Camera
- */
- VisionPortal portal = new VisionPortal.Builder()
- .addProcessor(colorSensor)
- .setCameraResolution(new Size(320, 240))
- .setCamera(hardwareMap.get(WebcamName.class, "Webcam 1"))
- .build();
-
- telemetry.setMsTransmissionInterval(50); // Speed up telemetry updates, Just use for debugging.
-
- // WARNING: To be able to view the stream preview on the Driver Station, this code runs in INIT mode.
- while (opModeIsActive() || opModeInInit())
- {
- telemetry.addData("DS preview on/off", "3 dots, Camera Stream\n");
-
- // Request the most recent color analysis.
- // This will return the closest matching colorSwatch and the predominant RGB color.
- // Note: to take actions based on the detected color, simply use the colorSwatch in a comparison or switch.
- // eg:
- // if (result.closestSwatch == PredominantColorProcessor.Swatch.RED) {... some code ...}
- PredominantColorProcessor.Result result = colorSensor.getAnalysis();
-
- // Display the Color Sensor result.
- telemetry.addData("Best Match:", result.closestSwatch);
- telemetry.addLine(String.format("R %3d, G %3d, B %3d", Color.red(result.rgb), Color.green(result.rgb), Color.blue(result.rgb)));
- telemetry.update();
-
- sleep(20);
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveByEncoder_Linear.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveByEncoder_Linear.java
deleted file mode 100644
index 63293d0c..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveByEncoder_Linear.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.Autonomous;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.util.ElapsedTime;
-
-/*
- * This OpMode illustrates the concept of driving a path based on encoder counts.
- * The code is structured as a LinearOpMode
- *
- * The code REQUIRES that you DO have encoders on the wheels,
- * otherwise you would use: RobotAutoDriveByTime;
- *
- * This code ALSO requires that the drive Motors have been configured such that a positive
- * power command moves them forward, and causes the encoders to count UP.
- *
- * The desired path in this example is:
- * - Drive forward for 48 inches
- * - Spin right for 12 Inches
- * - Drive Backward for 24 inches
- * - Stop and close the claw.
- *
- * The code is written using a method called: encoderDrive(speed, leftInches, rightInches, timeoutS)
- * that performs the actual movement.
- * This method assumes that each movement is relative to the last stopping place.
- * There are other ways to perform encoder based moves, but this method is probably the simplest.
- * This code uses the RUN_TO_POSITION mode to enable the Motor controllers to generate the run profile
- *
- * 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
- */
-
-@Autonomous(name="Robot: Auto Drive By Encoder", group="Robot")
-@Disabled
-public class RobotAutoDriveByEncoder_Linear extends LinearOpMode {
-
- /* Declare OpMode members. */
- private DcMotor leftDrive = null;
- private DcMotor rightDrive = null;
-
- private ElapsedTime runtime = new ElapsedTime();
-
- // Calculate the COUNTS_PER_INCH for your specific drive train.
- // Go to your motor vendor website to determine your motor's COUNTS_PER_MOTOR_REV
- // For external drive gearing, set DRIVE_GEAR_REDUCTION as needed.
- // For example, use a value of 2.0 for a 12-tooth spur gear driving a 24-tooth spur gear.
- // This is gearing DOWN for less speed and more torque.
- // For gearing UP, use a gear ratio less than 1.0. Note this will affect the direction of wheel rotation.
- static final double COUNTS_PER_MOTOR_REV = 1440 ; // eg: TETRIX Motor Encoder
- static final double DRIVE_GEAR_REDUCTION = 1.0 ; // No External Gearing.
- static final double WHEEL_DIAMETER_INCHES = 4.0 ; // For figuring circumference
- static final double COUNTS_PER_INCH = (COUNTS_PER_MOTOR_REV * DRIVE_GEAR_REDUCTION) /
- (WHEEL_DIAMETER_INCHES * 3.1415);
- static final double DRIVE_SPEED = 0.6;
- static final double TURN_SPEED = 0.5;
-
- @Override
- public void runOpMode() {
-
- // Initialize the drive system variables.
- leftDrive = hardwareMap.get(DcMotor.class, "left_drive");
- rightDrive = hardwareMap.get(DcMotor.class, "right_drive");
-
- // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
- // When run, this OpMode should start both motors driving forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Gear Reduction or 90 Deg drives may require direction flips
- leftDrive.setDirection(DcMotor.Direction.REVERSE);
- rightDrive.setDirection(DcMotor.Direction.FORWARD);
-
- leftDrive.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
- rightDrive.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
-
- leftDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- rightDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
-
- // Send telemetry message to indicate successful Encoder reset
- telemetry.addData("Starting at", "%7d :%7d",
- leftDrive.getCurrentPosition(),
- rightDrive.getCurrentPosition());
- telemetry.update();
-
- // Wait for the game to start (driver presses START)
- waitForStart();
-
- // Step through each leg of the path,
- // Note: Reverse movement is obtained by setting a negative distance (not speed)
- encoderDrive(DRIVE_SPEED, 48, 48, 5.0); // S1: Forward 47 Inches with 5 Sec timeout
- encoderDrive(TURN_SPEED, 12, -12, 4.0); // S2: Turn Right 12 Inches with 4 Sec timeout
- encoderDrive(DRIVE_SPEED, -24, -24, 4.0); // S3: Reverse 24 Inches with 4 Sec timeout
-
- telemetry.addData("Path", "Complete");
- telemetry.update();
- sleep(1000); // pause to display final telemetry message.
- }
-
- /*
- * Method to perform a relative move, based on encoder counts.
- * Encoders are not reset as the move is based on the current position.
- * Move will stop if any of three conditions occur:
- * 1) Move gets to the desired position
- * 2) Move runs out of time
- * 3) Driver stops the OpMode running.
- */
- public void encoderDrive(double speed,
- double leftInches, double rightInches,
- double timeoutS) {
- int newLeftTarget;
- int newRightTarget;
-
- // Ensure that the OpMode is still active
- if (opModeIsActive()) {
-
- // Determine new target position, and pass to motor controller
- newLeftTarget = leftDrive.getCurrentPosition() + (int)(leftInches * COUNTS_PER_INCH);
- newRightTarget = rightDrive.getCurrentPosition() + (int)(rightInches * COUNTS_PER_INCH);
- leftDrive.setTargetPosition(newLeftTarget);
- rightDrive.setTargetPosition(newRightTarget);
-
- // Turn On RUN_TO_POSITION
- leftDrive.setMode(DcMotor.RunMode.RUN_TO_POSITION);
- rightDrive.setMode(DcMotor.RunMode.RUN_TO_POSITION);
-
- // reset the timeout time and start motion.
- runtime.reset();
- leftDrive.setPower(Math.abs(speed));
- rightDrive.setPower(Math.abs(speed));
-
- // keep looping while we are still active, and there is time left, and both motors are running.
- // Note: We use (isBusy() && isBusy()) in the loop test, which means that when EITHER motor hits
- // its target position, the motion will stop. This is "safer" in the event that the robot will
- // always end the motion as soon as possible.
- // However, if you require that BOTH motors have finished their moves before the robot continues
- // onto the next step, use (isBusy() || isBusy()) in the loop test.
- while (opModeIsActive() &&
- (runtime.seconds() < timeoutS) &&
- (leftDrive.isBusy() && rightDrive.isBusy())) {
-
- // Display it for the driver.
- telemetry.addData("Running to", " %7d :%7d", newLeftTarget, newRightTarget);
- telemetry.addData("Currently at", " at %7d :%7d",
- leftDrive.getCurrentPosition(), rightDrive.getCurrentPosition());
- telemetry.update();
- }
-
- // Stop all motion;
- leftDrive.setPower(0);
- rightDrive.setPower(0);
-
- // Turn off RUN_TO_POSITION
- leftDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- rightDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
-
- sleep(250); // optional pause after each move.
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveByGyro_Linear.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveByGyro_Linear.java
deleted file mode 100644
index ab709344..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveByGyro_Linear.java
+++ /dev/null
@@ -1,429 +0,0 @@
-/* Copyright (c) 2022 FIRST. 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.rev.RevHubOrientationOnRobot;
-import com.qualcomm.robotcore.eventloop.opmode.Autonomous;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.hardware.IMU;
-import com.qualcomm.robotcore.util.ElapsedTime;
-import com.qualcomm.robotcore.util.Range;
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-import org.firstinspires.ftc.robotcore.external.navigation.YawPitchRollAngles;
-
-/*
- * This OpMode illustrates the concept of driving an autonomous path based on Gyro (IMU) heading and encoder counts.
- * The code is structured as a LinearOpMode
- *
- * The path to be followed by the robot is built from a series of drive, turn or pause steps.
- * Each step on the path is defined by a single function call, and these can be strung together in any order.
- *
- * The code REQUIRES that you have encoders on the drive motors, otherwise you should use: RobotAutoDriveByTime;
- *
- * This code uses the Universal IMU interface so it will work with either the BNO055, or BHI260 IMU.
- * To run as written, the Control/Expansion hub should be mounted horizontally on a flat part of the robot chassis.
- * The REV Logo should be facing UP, and the USB port should be facing forward.
- * If this is not the configuration of your REV Control Hub, then the code should be modified to reflect the correct orientation.
- *
- * This sample requires that the drive Motors have been configured with names : left_drive and right_drive.
- * It also requires that a positive power command moves both motors forward, and causes the encoders to count UP.
- * So please verify that both of your motors move the robot forward on the first move. If not, make the required correction.
- * See the beginning of runOpMode() to set the FORWARD/REVERSE option for each motor.
- *
- * This code uses RUN_TO_POSITION mode for driving straight, and RUN_USING_ENCODER mode for turning and holding.
- * Note: This code implements the requirement of calling setTargetPosition() at least once before switching to RUN_TO_POSITION mode.
- *
- * Notes:
- *
- * 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.
- * 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,
- * which means that a Positive rotation is Counter Clockwise, looking down on the field.
- * This is consistent with the FTC field coordinate conventions set out in the document:
- * https://ftc-docs.firstinspires.org/field-coordinate-system
- *
- * Control Approach.
- *
- * To reach, or maintain a required heading, this code implements a basic Proportional Controller where:
- *
- * Steering power = Heading Error * Proportional Gain.
- *
- * "Heading Error" is calculated by taking the difference between the desired heading and the actual heading,
- * and then "normalizing" it by converting it to a value in the +/- 180 degree range.
- *
- * "Proportional Gain" is a constant that YOU choose to set the "strength" of the steering response.
- *
- * Use Android Studio to Copy this Class, and Paste it into your "TeamCode" folder with a new name.
- * Remove or comment out the @Disabled line to add this OpMode to the Driver Station OpMode list
- */
-
-@Autonomous(name="Robot: Auto Drive By Gyro", group="Robot")
-@Disabled
-public class RobotAutoDriveByGyro_Linear extends LinearOpMode {
-
- /* Declare OpMode members. */
- private DcMotor leftDrive = null;
- private DcMotor rightDrive = null;
- private IMU imu = null; // Control/Expansion Hub IMU
-
- private double headingError = 0;
-
- // These variable are declared here (as class members) so they can be updated in various methods,
- // but still be displayed by sendTelemetry()
- private double targetHeading = 0;
- private double driveSpeed = 0;
- private double turnSpeed = 0;
- private double leftSpeed = 0;
- private double rightSpeed = 0;
- private int leftTarget = 0;
- private int rightTarget = 0;
-
- // Calculate the COUNTS_PER_INCH for your specific drive train.
- // Go to your motor vendor website to determine your motor's COUNTS_PER_MOTOR_REV
- // For external drive gearing, set DRIVE_GEAR_REDUCTION as needed.
- // For example, use a value of 2.0 for a 12-tooth spur gear driving a 24-tooth spur gear.
- // This is gearing DOWN for less speed and more torque.
- // For gearing UP, use a gear ratio less than 1.0. Note this will affect the direction of wheel rotation.
- static final double COUNTS_PER_MOTOR_REV = 537.7 ; // eg: GoBILDA 312 RPM Yellow Jacket
- static final double DRIVE_GEAR_REDUCTION = 1.0 ; // No External Gearing.
- static final double WHEEL_DIAMETER_INCHES = 4.0 ; // For figuring circumference
- static final double COUNTS_PER_INCH = (COUNTS_PER_MOTOR_REV * DRIVE_GEAR_REDUCTION) /
- (WHEEL_DIAMETER_INCHES * 3.1415);
-
- // These constants define the desired driving/control characteristics
- // 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 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.
- // 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".
- // 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 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)
- 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.
-
-
- @Override
- public void runOpMode() {
-
- // Initialize the drive system variables.
- leftDrive = hardwareMap.get(DcMotor.class, "left_drive");
- rightDrive = hardwareMap.get(DcMotor.class, "right_drive");
-
- // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
- // When run, this OpMode should start both motors driving forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Gear Reduction or 90 Deg drives may require direction flips
- leftDrive.setDirection(DcMotor.Direction.REVERSE);
- rightDrive.setDirection(DcMotor.Direction.FORWARD);
-
- /* The next two lines define Hub orientation.
- * The Default Orientation (shown) is when a hub is mounted horizontally with the printed logo pointing UP and the USB port pointing FORWARD.
- *
- * To Do: EDIT these two lines to match YOUR mounting configuration.
- */
- RevHubOrientationOnRobot.LogoFacingDirection logoDirection = RevHubOrientationOnRobot.LogoFacingDirection.UP;
- RevHubOrientationOnRobot.UsbFacingDirection usbDirection = RevHubOrientationOnRobot.UsbFacingDirection.FORWARD;
- RevHubOrientationOnRobot orientationOnRobot = new RevHubOrientationOnRobot(logoDirection, usbDirection);
-
- // Now initialize the IMU with this mounting orientation
- // This sample expects the IMU to be in a REV Hub and named "imu".
- imu = hardwareMap.get(IMU.class, "imu");
- imu.initialize(new IMU.Parameters(orientationOnRobot));
-
- // Ensure the robot is stationary. Reset the encoders and set the motors to BRAKE mode
- leftDrive.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
- rightDrive.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
- leftDrive.setZeroPowerBehavior(DcMotor.ZeroPowerBehavior.BRAKE);
- rightDrive.setZeroPowerBehavior(DcMotor.ZeroPowerBehavior.BRAKE);
-
- // Wait for the game to start (Display Gyro value while waiting)
- while (opModeInInit()) {
- telemetry.addData(">", "Robot Heading = %4.0f", getHeading());
- telemetry.update();
- }
-
- // Set the encoders for closed loop speed control, and reset the heading.
- leftDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- rightDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- imu.resetYaw();
-
- // Step through each leg of the path,
- // Notes: Reverse movement is obtained by setting a negative distance (not speed)
- // holdHeading() is used after turns to let the heading stabilize
- // Add a sleep(2000) after any step to keep the telemetry data visible for review
-
- driveStraight(DRIVE_SPEED, 24.0, 0.0); // Drive Forward 24"
- turnToHeading( TURN_SPEED, -45.0); // Turn CW to -45 Degrees
- holdHeading( TURN_SPEED, -45.0, 0.5); // Hold -45 Deg heading for a 1/2 second
-
- driveStraight(DRIVE_SPEED, 17.0, -45.0); // Drive Forward 17" at -45 degrees (12"x and 12"y)
- turnToHeading( TURN_SPEED, 45.0); // Turn CCW to 45 Degrees
- holdHeading( TURN_SPEED, 45.0, 0.5); // Hold 45 Deg heading for a 1/2 second
-
- driveStraight(DRIVE_SPEED, 17.0, 45.0); // Drive Forward 17" at 45 degrees (-12"x and 12"y)
- turnToHeading( TURN_SPEED, 0.0); // Turn CW to 0 Degrees
- holdHeading( TURN_SPEED, 0.0, 1.0); // Hold 0 Deg heading for 1 second
-
- driveStraight(DRIVE_SPEED,-48.0, 0.0); // Drive in Reverse 48" (should return to approx. staring position)
-
- telemetry.addData("Path", "Complete");
- telemetry.update();
- sleep(1000); // Pause to display last telemetry message.
- }
-
- /*
- * ====================================================================================================
- * Driving "Helper" functions are below this line.
- * These provide the high and low level methods that handle driving straight and turning.
- * ====================================================================================================
- */
-
- // ********** HIGH Level driving functions. ********************
-
- /**
- * Drive in a straight line, on a fixed compass heading (angle), based on encoder counts.
- * Move will stop if either of these conditions occur:
- * 1) Move gets to the desired position
- * 2) Driver stops the OpMode running.
- *
- * @param maxDriveSpeed MAX Speed for forward/rev motion (range 0 to +1.0) .
- * @param distance Distance (in inches) to move from current position. Negative distance means move backward.
- * @param heading Absolute Heading Angle (in Degrees) relative to last gyro reset.
- * 0 = fwd. +ve is CCW from fwd. -ve is CW from forward.
- * If a relative angle is required, add/subtract from the current robotHeading.
- */
- public void driveStraight(double maxDriveSpeed,
- double distance,
- double heading) {
-
- // Ensure that the OpMode is still active
- if (opModeIsActive()) {
-
- // Determine new target position, and pass to motor controller
- int moveCounts = (int)(distance * COUNTS_PER_INCH);
- leftTarget = leftDrive.getCurrentPosition() + moveCounts;
- rightTarget = rightDrive.getCurrentPosition() + moveCounts;
-
- // Set Target FIRST, then turn on RUN_TO_POSITION
- leftDrive.setTargetPosition(leftTarget);
- rightDrive.setTargetPosition(rightTarget);
-
- leftDrive.setMode(DcMotor.RunMode.RUN_TO_POSITION);
- rightDrive.setMode(DcMotor.RunMode.RUN_TO_POSITION);
-
- // Set the required driving speed (must be positive for RUN_TO_POSITION)
- // Start driving straight, and then enter the control loop
- maxDriveSpeed = Math.abs(maxDriveSpeed);
- moveRobot(maxDriveSpeed, 0);
-
- // keep looping while we are still active, and BOTH motors are running.
- while (opModeIsActive() &&
- (leftDrive.isBusy() && rightDrive.isBusy())) {
-
- // Determine required steering to keep on heading
- turnSpeed = getSteeringCorrection(heading, P_DRIVE_GAIN);
-
- // if driving in reverse, the motor correction also needs to be reversed
- if (distance < 0)
- turnSpeed *= -1.0;
-
- // Apply the turning correction to the current driving speed.
- moveRobot(driveSpeed, turnSpeed);
-
- // Display drive status for the driver.
- sendTelemetry(true);
- }
-
- // Stop all motion & Turn off RUN_TO_POSITION
- moveRobot(0, 0);
- leftDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- rightDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- }
- }
-
- /**
- * Spin on the central axis to point in a new direction.
- *
- * Move will stop if either of these conditions occur:
- *
- * 1) Move gets to the heading (angle)
- *
- * 2) Driver stops the OpMode running.
- *
- * @param maxTurnSpeed Desired MAX speed of turn. (range 0 to +1.0)
- * @param heading Absolute Heading Angle (in Degrees) relative to last gyro reset.
- * 0 = fwd. +ve is CCW from fwd. -ve is CW from forward.
- * If a relative angle is required, add/subtract from current heading.
- */
- public void turnToHeading(double maxTurnSpeed, double heading) {
-
- // Run getSteeringCorrection() once to pre-calculate the current error
- getSteeringCorrection(heading, P_DRIVE_GAIN);
-
- // keep looping while we are still active, and not on heading.
- while (opModeIsActive() && (Math.abs(headingError) > HEADING_THRESHOLD)) {
-
- // Determine required steering to keep on heading
- turnSpeed = getSteeringCorrection(heading, P_TURN_GAIN);
-
- // Clip the speed to the maximum permitted value.
- turnSpeed = Range.clip(turnSpeed, -maxTurnSpeed, maxTurnSpeed);
-
- // Pivot in place by applying the turning correction
- moveRobot(0, turnSpeed);
-
- // Display drive status for the driver.
- sendTelemetry(false);
- }
-
- // Stop all motion;
- moveRobot(0, 0);
- }
-
- /**
- * Obtain & hold a heading for a finite amount of time
- *
- * Move will stop once the requested time has elapsed
- *
- * 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 heading Absolute Heading Angle (in Degrees) relative to last gyro reset.
- * 0 = fwd. +ve is CCW from fwd. -ve is CW from forward.
- * If a relative angle is required, add/subtract from current heading.
- * @param holdTime Length of time (in seconds) to hold the specified heading.
- */
- public void holdHeading(double maxTurnSpeed, double heading, double holdTime) {
-
- ElapsedTime holdTimer = new ElapsedTime();
- holdTimer.reset();
-
- // keep looping while we have time remaining.
- while (opModeIsActive() && (holdTimer.time() < holdTime)) {
- // Determine required steering to keep on heading
- turnSpeed = getSteeringCorrection(heading, P_TURN_GAIN);
-
- // Clip the speed to the maximum permitted value.
- turnSpeed = Range.clip(turnSpeed, -maxTurnSpeed, maxTurnSpeed);
-
- // Pivot in place by applying the turning correction
- moveRobot(0, turnSpeed);
-
- // Display drive status for the driver.
- sendTelemetry(false);
- }
-
- // Stop all motion;
- moveRobot(0, 0);
- }
-
- // ********** LOW Level driving functions. ********************
-
- /**
- * Use a Proportional Controller to determine how much steering correction is required.
- *
- * @param desiredHeading The desired absolute heading (relative to last heading reset)
- * @param proportionalGain Gain factor applied to heading error to obtain turning power.
- * @return Turning power needed to get to required heading.
- */
- public double getSteeringCorrection(double desiredHeading, double proportionalGain) {
- targetHeading = desiredHeading; // Save for telemetry
-
- // Determine the heading current error
- headingError = targetHeading - getHeading();
-
- // Normalize the error to be within +/- 180 degrees
- while (headingError > 180) headingError -= 360;
- while (headingError <= -180) headingError += 360;
-
- // Multiply the error by the gain to determine the required steering correction/ Limit the result to +/- 1.0
- return Range.clip(headingError * proportionalGain, -1, 1);
- }
-
- /**
- * Take separate drive (fwd/rev) and turn (right/left) requests,
- * combines them, and applies the appropriate speed commands to the left and right wheel motors.
- * @param drive forward motor speed
- * @param turn clockwise turning motor speed.
- */
- public void moveRobot(double drive, double turn) {
- driveSpeed = drive; // save this value as a class member so it can be used by telemetry.
- turnSpeed = turn; // save this value as a class member so it can be used by telemetry.
-
- leftSpeed = drive - turn;
- rightSpeed = drive + turn;
-
- // Scale speeds down if either one exceeds +/- 1.0;
- double max = Math.max(Math.abs(leftSpeed), Math.abs(rightSpeed));
- if (max > 1.0)
- {
- leftSpeed /= max;
- rightSpeed /= max;
- }
-
- leftDrive.setPower(leftSpeed);
- rightDrive.setPower(rightSpeed);
- }
-
- /**
- * Display the various control parameters while driving
- *
- * @param straight Set to true if we are driving straight, and the encoder positions should be included in the telemetry.
- */
- private void sendTelemetry(boolean straight) {
-
- if (straight) {
- telemetry.addData("Motion", "Drive Straight");
- telemetry.addData("Target Pos L:R", "%7d:%7d", leftTarget, rightTarget);
- telemetry.addData("Actual Pos L:R", "%7d:%7d", leftDrive.getCurrentPosition(),
- rightDrive.getCurrentPosition());
- } else {
- telemetry.addData("Motion", "Turning");
- }
-
- telemetry.addData("Heading- Target : Current", "%5.2f : %5.0f", targetHeading, getHeading());
- telemetry.addData("Error : Steer Pwr", "%5.1f : %5.1f", headingError, turnSpeed);
- telemetry.addData("Wheel Speeds L : R", "%5.2f : %5.2f", leftSpeed, rightSpeed);
- telemetry.update();
- }
-
- /**
- * read the Robot heading directly from the IMU (in degrees)
- */
- public double getHeading() {
- YawPitchRollAngles orientation = imu.getRobotYawPitchRollAngles();
- return orientation.getYaw(AngleUnit.DEGREES);
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveByTime_Linear.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveByTime_Linear.java
deleted file mode 100644
index a7147481..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveByTime_Linear.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.Autonomous;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.util.ElapsedTime;
-
-/*
- * This OpMode illustrates the concept of driving a path based on time.
- * The code is structured as a LinearOpMode
- *
- * The code assumes that you do NOT have encoders on the wheels,
- * otherwise you would use: RobotAutoDriveByEncoder;
- *
- * The desired path in this example is:
- * - Drive forward for 3 seconds
- * - Spin right for 1.3 seconds
- * - Drive Backward for 1 Second
- *
- * The code is written in a simple form with no optimizations.
- * However, there are several ways that this type of sequence could be streamlined,
- *
- * 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
- */
-
-@Autonomous(name="Robot: Auto Drive By Time", group="Robot")
-@Disabled
-public class RobotAutoDriveByTime_Linear extends LinearOpMode {
-
- /* Declare OpMode members. */
- private DcMotor leftDrive = null;
- private DcMotor rightDrive = null;
-
- private ElapsedTime runtime = new ElapsedTime();
-
-
- static final double FORWARD_SPEED = 0.6;
- static final double TURN_SPEED = 0.5;
-
- @Override
- public void runOpMode() {
-
- // Initialize the drive system variables.
- leftDrive = hardwareMap.get(DcMotor.class, "left_drive");
- rightDrive = hardwareMap.get(DcMotor.class, "right_drive");
-
- // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
- // When run, this OpMode should start both motors driving forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Gear Reduction or 90 Deg drives may require direction flips
- leftDrive.setDirection(DcMotor.Direction.REVERSE);
- rightDrive.setDirection(DcMotor.Direction.FORWARD);
-
- // Send telemetry message to signify robot waiting;
- telemetry.addData("Status", "Ready to run"); //
- telemetry.update();
-
- // Wait for the game to start (driver presses START)
- waitForStart();
-
- // 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
- leftDrive.setPower(FORWARD_SPEED);
- rightDrive.setPower(FORWARD_SPEED);
- runtime.reset();
- while (opModeIsActive() && (runtime.seconds() < 3.0)) {
- telemetry.addData("Path", "Leg 1: %4.1f S Elapsed", runtime.seconds());
- telemetry.update();
- }
-
- // Step 2: Spin right for 1.3 seconds
- leftDrive.setPower(TURN_SPEED);
- rightDrive.setPower(-TURN_SPEED);
- runtime.reset();
- while (opModeIsActive() && (runtime.seconds() < 1.3)) {
- telemetry.addData("Path", "Leg 2: %4.1f S Elapsed", runtime.seconds());
- telemetry.update();
- }
-
- // Step 3: Drive Backward for 1 Second
- leftDrive.setPower(-FORWARD_SPEED);
- rightDrive.setPower(-FORWARD_SPEED);
- runtime.reset();
- while (opModeIsActive() && (runtime.seconds() < 1.0)) {
- telemetry.addData("Path", "Leg 3: %4.1f S Elapsed", runtime.seconds());
- telemetry.update();
- }
-
- // Step 4: Stop
- leftDrive.setPower(0);
- rightDrive.setPower(0);
-
- telemetry.addData("Path", "Complete");
- telemetry.update();
- sleep(1000);
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveToAprilTagOmni.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveToAprilTagOmni.java
deleted file mode 100644
index 9bac0069..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveToAprilTagOmni.java
+++ /dev/null
@@ -1,321 +0,0 @@
-/* Copyright (c) 2023 FIRST. 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 com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.util.Range;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.BuiltinCameraDirection;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.controls.ExposureControl;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.controls.GainControl;
-import org.firstinspires.ftc.vision.VisionPortal;
-import org.firstinspires.ftc.vision.apriltag.AprilTagDetection;
-import org.firstinspires.ftc.vision.apriltag.AprilTagProcessor;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/*
- * This OpMode illustrates using a camera to locate and drive towards a specific AprilTag.
- * The code assumes a Holonomic (Mecanum or X Drive) Robot.
- *
- * 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
- *
- * When an AprilTag in the TagLibrary is detected, the SDK provides location and orientation of the tag, relative to the camera.
- * This information is provided in the "ftcPose" member of the returned "detection", and is explained in the ftc-docs page linked below.
- * https://ftc-docs.firstinspires.org/apriltag-detection-values
- *
- * The drive goal is to rotate to keep the Tag centered in the camera, while strafing to be directly in front of the tag, and
- * driving towards the tag to achieve the desired distance.
- * To reduce any motion blur (which will interrupt the detection process) the Camera exposure is reduced to a very low value (5mS)
- * You can determine the best Exposure and Gain values by using the ConceptAprilTagOptimizeExposure OpMode in this Samples folder.
- *
- * 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.
- * 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.
- *
- * 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.
- *
- * Press and hold the *Left Bumper* to enable the automatic "Drive to target" mode.
- * Release the Left Bumper to return to manual driving mode.
- *
- * Under "Drive To Target" mode, the robot has three goals:
- * 1) Turn the robot to always keep the Tag centered on the camera frame. (Use the Target Bearing to turn the robot.)
- * 2) Strafe the robot towards the centerline of the Tag, so it approaches directly in front of the tag. (Use the Target Yaw to strafe the robot)
- * 3) Drive towards the Tag to get to the desired distance. (Use Tag Range to drive the robot forward/backward)
- *
- * Use DESIRED_DISTANCE to set how close you want the robot to get to the target.
- * Speed and Turn sensitivity can be adjusted using the SPEED_GAIN, STRAFE_GAIN and TURN_GAIN constants.
- *
- * Use Android Studio to Copy this Class, and Paste it into the TeamCode/src/main/java/org/firstinspires/ftc/teamcode folder.
- * Remove or comment out the @Disabled line to add this OpMode to the Driver Station OpMode list.
- *
- */
-
-@TeleOp(name="Omni Drive To AprilTag", group = "Concept")
-@Disabled
-public class RobotAutoDriveToAprilTagOmni extends LinearOpMode
-{
- // Adjust these numbers to suit your robot.
- final double DESIRED_DISTANCE = 12.0; // this is how close the camera should get to the target (inches)
-
- // 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.
- // 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". 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". 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". 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_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)
-
- private DcMotor leftFrontDrive = null; // Used to control the left front drive wheel
- private DcMotor rightFrontDrive = null; // Used to control the right front drive wheel
- private DcMotor leftBackDrive = null; // Used to control the left back drive wheel
- private DcMotor rightBackDrive = null; // Used to control the right back drive wheel
-
- private static final boolean USE_WEBCAM = true; // Set true to use a webcam, or false for a phone camera
- private static final int DESIRED_TAG_ID = -1; // Choose the tag you want to approach or set to -1 for ANY tag.
- private VisionPortal visionPortal; // Used to manage the video source.
- private AprilTagProcessor aprilTag; // Used for managing the AprilTag detection process.
- private AprilTagDetection desiredTag = null; // Used to hold the data for a detected AprilTag
-
- @Override public void runOpMode()
- {
- boolean targetFound = false; // Set to true when an AprilTag target is detected
- double drive = 0; // Desired forward power/speed (-1 to +1)
- double strafe = 0; // Desired strafe power/speed (-1 to +1)
- double turn = 0; // Desired turning power/speed (-1 to +1)
-
- // Initialize the Apriltag Detection process
- initAprilTag();
-
- // Initialize the hardware variables. Note that the strings used here as parameters
- // to 'get' must match the names assigned during the robot configuration.
- // step (using the FTC Robot Controller app on the phone).
- leftFrontDrive = hardwareMap.get(DcMotor.class, "leftfront_drive");
- rightFrontDrive = hardwareMap.get(DcMotor.class, "rightfront_drive");
- leftBackDrive = hardwareMap.get(DcMotor.class, "leftback_drive");
- rightBackDrive = hardwareMap.get(DcMotor.class, "rightback_drive");
-
- // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
- // When run, this OpMode should start both motors driving forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Gear Reduction or 90 Deg drives may require direction flips
- leftFrontDrive.setDirection(DcMotor.Direction.REVERSE);
- leftBackDrive.setDirection(DcMotor.Direction.REVERSE);
- rightFrontDrive.setDirection(DcMotor.Direction.FORWARD);
- rightBackDrive.setDirection(DcMotor.Direction.FORWARD);
-
- if (USE_WEBCAM)
- setManualExposure(6, 250); // Use low exposure time to reduce motion blur
-
- // Wait for driver to press start
- telemetry.addData("Camera preview on/off", "3 dots, Camera Stream");
- telemetry.addData(">", "Touch START to start OpMode");
- telemetry.update();
- waitForStart();
-
- while (opModeIsActive())
- {
- targetFound = false;
- desiredTag = null;
-
- // Step through the list of detected tags and look for a matching tag
- List currentDetections = aprilTag.getDetections();
- for (AprilTagDetection detection : currentDetections) {
- // Look to see if we have size info on this tag.
- if (detection.metadata != null) {
- // Check to see if we want to track towards this tag.
- if ((DESIRED_TAG_ID < 0) || (detection.id == DESIRED_TAG_ID)) {
- // Yes, we want to use this tag.
- targetFound = true;
- desiredTag = detection;
- break; // don't look any further.
- } else {
- // This tag is in the library, but we do not want to track it right now.
- telemetry.addData("Skipping", "Tag ID %d is not desired", detection.id);
- }
- } else {
- // This tag is NOT in the library, so we don't have enough information to track to it.
- telemetry.addData("Unknown", "Tag ID %d is not in TagLibrary", detection.id);
- }
- }
-
- // Tell the driver what we see, and what to do.
- if (targetFound) {
- telemetry.addData("\n>","HOLD Left-Bumper to Drive to Target\n");
- telemetry.addData("Found", "ID %d (%s)", desiredTag.id, desiredTag.metadata.name);
- telemetry.addData("Range", "%5.1f inches", desiredTag.ftcPose.range);
- telemetry.addData("Bearing","%3.0f degrees", desiredTag.ftcPose.bearing);
- telemetry.addData("Yaw","%3.0f degrees", desiredTag.ftcPose.yaw);
- } else {
- telemetry.addData("\n>","Drive using joysticks to find valid target\n");
- }
-
- // If Left Bumper is being pressed, AND we have found the desired target, Drive to target Automatically .
- if (gamepad1.left_bumper && targetFound) {
-
- // Determine heading, range and Yaw (tag image rotation) error so we can use them to control the robot automatically.
- double rangeError = (desiredTag.ftcPose.range - DESIRED_DISTANCE);
- double headingError = desiredTag.ftcPose.bearing;
- double yawError = desiredTag.ftcPose.yaw;
-
- // Use the speed and turn "gains" to calculate how we want the robot to move.
- drive = Range.clip(rangeError * SPEED_GAIN, -MAX_AUTO_SPEED, MAX_AUTO_SPEED);
- turn = Range.clip(headingError * TURN_GAIN, -MAX_AUTO_TURN, MAX_AUTO_TURN) ;
- strafe = Range.clip(-yawError * STRAFE_GAIN, -MAX_AUTO_STRAFE, MAX_AUTO_STRAFE);
-
- telemetry.addData("Auto","Drive %5.2f, Strafe %5.2f, Turn %5.2f ", drive, strafe, turn);
- } else {
-
- // drive using manual POV Joystick mode. Slow things down to make the robot more controlable.
- drive = -gamepad1.left_stick_y / 2.0; // Reduce drive rate to 50%.
- strafe = -gamepad1.left_stick_x / 2.0; // Reduce strafe rate to 50%.
- turn = -gamepad1.right_stick_x / 3.0; // Reduce turn rate to 33%.
- telemetry.addData("Manual","Drive %5.2f, Strafe %5.2f, Turn %5.2f ", drive, strafe, turn);
- }
- telemetry.update();
-
- // Apply desired axes motions to the drivetrain.
- moveRobot(drive, strafe, turn);
- sleep(10);
- }
- }
-
- /**
- * Move robot according to desired axes motions
- *
- * Positive X is forward
- *
- * Positive Y is strafe left
- *
- * Positive Yaw is counter-clockwise
- */
- public void moveRobot(double x, double y, double yaw) {
- // Calculate wheel powers.
- double leftFrontPower = x -y -yaw;
- double rightFrontPower = x +y +yaw;
- double leftBackPower = x +y -yaw;
- double rightBackPower = x -y +yaw;
-
- // Normalize wheel powers to be less than 1.0
- double max = Math.max(Math.abs(leftFrontPower), Math.abs(rightFrontPower));
- max = Math.max(max, Math.abs(leftBackPower));
- max = Math.max(max, Math.abs(rightBackPower));
-
- if (max > 1.0) {
- leftFrontPower /= max;
- rightFrontPower /= max;
- leftBackPower /= max;
- rightBackPower /= max;
- }
-
- // Send powers to the wheels.
- leftFrontDrive.setPower(leftFrontPower);
- rightFrontDrive.setPower(rightFrontPower);
- leftBackDrive.setPower(leftBackPower);
- rightBackDrive.setPower(rightBackPower);
- }
-
- /**
- * Initialize the AprilTag processor.
- */
- private void initAprilTag() {
- // Create the AprilTag processor by using a builder.
- aprilTag = new AprilTagProcessor.Builder().build();
-
- // Adjust Image Decimation to trade-off detection-range for detection-rate.
- // 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 = 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 5" Tag from 10 feet away at 30 Frames Per Second
- // Note: Decimation can be changed on-the-fly to adapt during a match.
- aprilTag.setDecimation(2);
-
- // Create the vision portal by using a builder.
- if (USE_WEBCAM) {
- visionPortal = new VisionPortal.Builder()
- .setCamera(hardwareMap.get(WebcamName.class, "Webcam 1"))
- .addProcessor(aprilTag)
- .build();
- } else {
- visionPortal = new VisionPortal.Builder()
- .setCamera(BuiltinCameraDirection.BACK)
- .addProcessor(aprilTag)
- .build();
- }
- }
-
- /*
- Manually set the camera gain and exposure.
- This can only be called AFTER calling initAprilTag(), and only works for Webcams;
- */
- private void setManualExposure(int exposureMS, int gain) {
- // Wait for the camera to be open, then use the controls
-
- if (visionPortal == null) {
- return;
- }
-
- // Make sure camera is streaming before we try to set the exposure controls
- if (visionPortal.getCameraState() != VisionPortal.CameraState.STREAMING) {
- telemetry.addData("Camera", "Waiting");
- telemetry.update();
- while (!isStopRequested() && (visionPortal.getCameraState() != VisionPortal.CameraState.STREAMING)) {
- sleep(20);
- }
- telemetry.addData("Camera", "Ready");
- telemetry.update();
- }
-
- // Set camera controls unless we are stopping.
- if (!isStopRequested())
- {
- ExposureControl exposureControl = visionPortal.getCameraControl(ExposureControl.class);
- if (exposureControl.getMode() != ExposureControl.Mode.Manual) {
- exposureControl.setMode(ExposureControl.Mode.Manual);
- sleep(50);
- }
- exposureControl.setExposure((long)exposureMS, TimeUnit.MILLISECONDS);
- sleep(20);
- GainControl gainControl = visionPortal.getCameraControl(GainControl.class);
- gainControl.setGain(gain);
- sleep(20);
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveToAprilTagTank.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveToAprilTagTank.java
deleted file mode 100644
index ba3eb4f9..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveToAprilTagTank.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/* Copyright (c) 2023 FIRST. 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 com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.util.Range;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.BuiltinCameraDirection;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.controls.ExposureControl;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.controls.GainControl;
-import org.firstinspires.ftc.vision.VisionPortal;
-import org.firstinspires.ftc.vision.apriltag.AprilTagDetection;
-import org.firstinspires.ftc.vision.apriltag.AprilTagProcessor;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/*
- * This OpMode illustrates using a camera to locate and drive towards a specific AprilTag.
- * The code assumes a basic two-wheel (Tank) Robot Drivetrain
- *
- * 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
- *
- * When an AprilTag in the TagLibrary is detected, the SDK provides location and orientation of the tag, relative to the camera.
- * This information is provided in the "ftcPose" member of the returned "detection", and is explained in the ftc-docs page linked below.
- * https://ftc-docs.firstinspires.org/apriltag-detection-values
- *
- * The driving goal is to rotate to keep the tag centered in the camera, while driving towards the tag to achieve the desired distance.
- * To reduce any motion blur (which will interrupt the detection process) the Camera exposure is reduced to a very low value (5mS)
- * You can determine the best exposure and gain values by using the ConceptAprilTagOptimizeExposure OpMode in this Samples folder.
- *
- * 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;
- * 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.
- *
- * 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).
- *
- * Manually drive the robot until it displays Target data on the Driver Station.
- * Press and hold the *Left Bumper* to enable the automatic "Drive to target" mode.
- * Release the Left Bumper to return to manual driving mode.
- *
- * Under "Drive To Target" mode, the robot has two goals:
- * 1) Turn the robot to always keep the Tag centered on the camera frame. (Use the Target Bearing to turn the robot.)
- * 2) Drive towards the Tag to get to the desired distance. (Use Tag Range to drive the robot forward/backward)
- *
- * Use DESIRED_DISTANCE to set how close you want the robot to get to the target.
- * Speed and Turn sensitivity can be adjusted using the SPEED_GAIN and TURN_GAIN constants.
- *
- * Use Android Studio to Copy this Class, and Paste it into the TeamCode/src/main/java/org/firstinspires/ftc/teamcode folder.
- * Remove or comment out the @Disabled line to add this OpMode to the Driver Station OpMode list.
- *
- */
-
-@TeleOp(name="Tank Drive To AprilTag", group = "Concept")
-@Disabled
-public class RobotAutoDriveToAprilTagTank extends LinearOpMode
-{
- // Adjust these numbers to suit your robot.
- final double DESIRED_DISTANCE = 12.0; // this is how close the camera should get to the target (inches)
-
- // 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.
- // 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". 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". 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_TURN = 0.25; // Clip the turn speed to this max value (adjust for your robot)
-
- private DcMotor leftDrive = null; // Used to control the left drive wheel
- private DcMotor rightDrive = null; // Used to control the right drive wheel
-
- private static final boolean USE_WEBCAM = true; // Set true to use a webcam, or false for a phone camera
- private static final int DESIRED_TAG_ID = -1; // Choose the tag you want to approach or set to -1 for ANY tag.
- private VisionPortal visionPortal; // Used to manage the video source.
- private AprilTagProcessor aprilTag; // Used for managing the AprilTag detection process.
- private AprilTagDetection desiredTag = null; // Used to hold the data for a detected AprilTag
-
- @Override public void runOpMode()
- {
- boolean targetFound = false; // Set to true when an AprilTag target is detected
- double drive = 0; // Desired forward power/speed (-1 to +1) +ve is forward
- double turn = 0; // Desired turning power/speed (-1 to +1) +ve is CounterClockwise
-
- // Initialize the Apriltag Detection process
- initAprilTag();
-
- // Initialize the hardware variables. Note that the strings used here as parameters
- // to 'get' must match the names assigned during the robot configuration.
- // step (using the FTC Robot Controller app on the phone).
- leftDrive = hardwareMap.get(DcMotor.class, "left_drive");
- rightDrive = hardwareMap.get(DcMotor.class, "right_drive");
-
- // To drive forward, most robots need the motor on one side to be reversed because the axles point in opposite directions.
- // When run, this OpMode should start both motors driving forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Single Gear Reduction or 90 Deg drives may require direction flips
- leftDrive.setDirection(DcMotor.Direction.REVERSE);
- rightDrive.setDirection(DcMotor.Direction.FORWARD);
-
- if (USE_WEBCAM)
- setManualExposure(6, 250); // Use low exposure time to reduce motion blur
-
- // Wait for the driver to press Start
- telemetry.addData("Camera preview on/off", "3 dots, Camera Stream");
- telemetry.addData(">", "Touch START to start OpMode");
- telemetry.update();
- waitForStart();
-
- while (opModeIsActive())
- {
- targetFound = false;
- desiredTag = null;
-
- // Step through the list of detected tags and look for a matching tag
- List currentDetections = aprilTag.getDetections();
- for (AprilTagDetection detection : currentDetections) {
- // Look to see if we have size info on this tag.
- if (detection.metadata != null) {
- // Check to see if we want to track towards this tag.
- if ((DESIRED_TAG_ID < 0) || (detection.id == DESIRED_TAG_ID)) {
- // Yes, we want to use this tag.
- targetFound = true;
- desiredTag = detection;
- break; // don't look any further.
- } else {
- // This tag is in the library, but we do not want to track it right now.
- telemetry.addData("Skipping", "Tag ID %d is not desired", detection.id);
- }
- } else {
- // This tag is NOT in the library, so we don't have enough information to track to it.
- telemetry.addData("Unknown", "Tag ID %d is not in TagLibrary", detection.id);
- }
- }
-
- // Tell the driver what we see, and what to do.
- if (targetFound) {
- telemetry.addData("\n>","HOLD Left-Bumper to Drive to Target\n");
- telemetry.addData("Found", "ID %d (%s)", desiredTag.id, desiredTag.metadata.name);
- telemetry.addData("Range", "%5.1f inches", desiredTag.ftcPose.range);
- telemetry.addData("Bearing","%3.0f degrees", desiredTag.ftcPose.bearing);
- } else {
- telemetry.addData("\n>","Drive using joysticks to find valid target\n");
- }
-
- // If Left Bumper is being pressed, AND we have found the desired target, Drive to target Automatically .
- if (gamepad1.left_bumper && targetFound) {
-
- // Determine heading and range error so we can use them to control the robot automatically.
- double rangeError = (desiredTag.ftcPose.range - DESIRED_DISTANCE);
- double headingError = desiredTag.ftcPose.bearing;
-
- // Use the speed and turn "gains" to calculate how we want the robot to move. Clip it to the maximum
- drive = Range.clip(rangeError * SPEED_GAIN, -MAX_AUTO_SPEED, MAX_AUTO_SPEED);
- turn = Range.clip(headingError * TURN_GAIN, -MAX_AUTO_TURN, MAX_AUTO_TURN) ;
-
- telemetry.addData("Auto","Drive %5.2f, Turn %5.2f", drive, turn);
- } else {
-
- // drive using manual POV Joystick mode.
- drive = -gamepad1.left_stick_y / 2.0; // Reduce drive rate to 50%.
- turn = -gamepad1.right_stick_x / 4.0; // Reduce turn rate to 25%.
- telemetry.addData("Manual","Drive %5.2f, Turn %5.2f", drive, turn);
- }
- telemetry.update();
-
- // Apply desired axes motions to the drivetrain.
- moveRobot(drive, turn);
- sleep(10);
- }
- }
-
- /**
- * Move robot according to desired axes motions
- *
- * Positive X is forward
- *
- * Positive Yaw is counter-clockwise
- */
- public void moveRobot(double x, double yaw) {
- // Calculate left and right wheel powers.
- double leftPower = x - yaw;
- double rightPower = x + yaw;
-
- // Normalize wheel powers to be less than 1.0
- double max = Math.max(Math.abs(leftPower), Math.abs(rightPower));
- if (max >1.0) {
- leftPower /= max;
- rightPower /= max;
- }
-
- // Send powers to the wheels.
- leftDrive.setPower(leftPower);
- rightDrive.setPower(rightPower);
- }
-
- /**
- * Initialize the AprilTag processor.
- */
- private void initAprilTag() {
- // Create the AprilTag processor by using a builder.
- aprilTag = new AprilTagProcessor.Builder().build();
-
- // Adjust Image Decimation to trade-off detection-range for detection-rate.
- // 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 = 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 5" Tag from 10 feet away at 30 Frames Per Second
- // Note: Decimation can be changed on-the-fly to adapt during a match.
- aprilTag.setDecimation(2);
-
- // Create the vision portal by using a builder.
- if (USE_WEBCAM) {
- visionPortal = new VisionPortal.Builder()
- .setCamera(hardwareMap.get(WebcamName.class, "Webcam 1"))
- .addProcessor(aprilTag)
- .build();
- } else {
- visionPortal = new VisionPortal.Builder()
- .setCamera(BuiltinCameraDirection.BACK)
- .addProcessor(aprilTag)
- .build();
- }
- }
-
- /*
- Manually set the camera gain and exposure.
- This can only be called AFTER calling initAprilTag(), and only works for Webcams;
- */
- private void setManualExposure(int exposureMS, int gain) {
- // Wait for the camera to be open, then use the controls
-
- if (visionPortal == null) {
- return;
- }
-
- // Make sure camera is streaming before we try to set the exposure controls
- if (visionPortal.getCameraState() != VisionPortal.CameraState.STREAMING) {
- telemetry.addData("Camera", "Waiting");
- telemetry.update();
- while (!isStopRequested() && (visionPortal.getCameraState() != VisionPortal.CameraState.STREAMING)) {
- sleep(20);
- }
- telemetry.addData("Camera", "Ready");
- telemetry.update();
- }
-
- // Set camera controls unless we are stopping.
- if (!isStopRequested())
- {
- ExposureControl exposureControl = visionPortal.getCameraControl(ExposureControl.class);
- if (exposureControl.getMode() != ExposureControl.Mode.Manual) {
- exposureControl.setMode(ExposureControl.Mode.Manual);
- sleep(50);
- }
- exposureControl.setExposure((long)exposureMS, TimeUnit.MILLISECONDS);
- sleep(20);
- GainControl gainControl = visionPortal.getCameraControl(GainControl.class);
- gainControl.setGain(gain);
- sleep(20);
- telemetry.addData("Camera", "Ready");
- telemetry.update();
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveToLine_Linear.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveToLine_Linear.java
deleted file mode 100644
index 780f2604..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveToLine_Linear.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.Autonomous;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.hardware.NormalizedColorSensor;
-import com.qualcomm.robotcore.hardware.NormalizedRGBA;
-import com.qualcomm.robotcore.hardware.SwitchableLight;
-
-/*
- * This OpMode illustrates the concept of driving up to a line and then stopping.
- * The code is structured as a LinearOpMode
- *
- * The Sensor used here can be a REV Color Sensor V2 or V3. Make sure the white LED is turned on.
- * The sensor can be plugged into any I2C port, and must be named "sensor_color" in the active configuration.
- *
- * Depending on the height of your color sensor, you may want to set the sensor "gain".
- * The higher the gain, the greater the reflected light reading will be.
- * Use the SensorColor sample in this folder to determine the minimum gain value that provides an
- * "Alpha" reading of 1.0 when you are on top of the white line. In this sample, we use a gain of 15
- * which works well with a Rev V2 color sensor
- *
- * Setting the correct WHITE_THRESHOLD value is key to stopping correctly.
- * This should be set halfway between the bare-tile, and white-line "Alpha" values.
- * The reflected light value can be read on the screen once the OpMode has been INIT, but before it is STARTED.
- * Move the sensor on and off the white line and note the min and max readings.
- * Edit this code to make WHITE_THRESHOLD halfway between the min and max.
- *
- * 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
- */
-
-@Autonomous(name="Robot: Auto Drive To Line", group="Robot")
-@Disabled
-public class RobotAutoDriveToLine_Linear extends LinearOpMode {
-
- /* Declare OpMode members. */
- private DcMotor leftDrive = null;
- private DcMotor rightDrive = null;
-
- /** The variable to store a reference to our color sensor hardware object */
- NormalizedColorSensor colorSensor;
-
- static final double WHITE_THRESHOLD = 0.5; // spans between 0.0 - 1.0 from dark to light
- static final double APPROACH_SPEED = 0.25;
-
- @Override
- public void runOpMode() {
-
- // Initialize the drive system variables.
- leftDrive = hardwareMap.get(DcMotor.class, "left_drive");
- rightDrive = hardwareMap.get(DcMotor.class, "right_drive");
-
- // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
- // When run, this OpMode should start both motors driving forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Gear Reduction or 90 Deg drives may require direction flips
- leftDrive.setDirection(DcMotor.Direction.REVERSE);
- rightDrive.setDirection(DcMotor.Direction.FORWARD);
-
- // If there are encoders connected, switch to RUN_USING_ENCODER mode for greater accuracy
- // leftDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- // rightDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
-
- // Get a reference to our sensor object. It's recommended to use NormalizedColorSensor over
- // ColorSensor, because NormalizedColorSensor consistently gives values between 0 and 1, while
- // the values you get from ColorSensor are dependent on the specific sensor you're using.
- colorSensor = hardwareMap.get(NormalizedColorSensor.class, "sensor_color");
-
- // If necessary, turn ON the white LED (if there is no LED switch on the sensor)
- if (colorSensor instanceof SwitchableLight) {
- ((SwitchableLight)colorSensor).enableLight(true);
- }
-
- // Some sensors allow you to set your light sensor gain for optimal sensitivity...
- // See the SensorColor sample in this folder for how to determine the optimal gain.
- // 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);
-
- // Wait for driver to press START)
- // Abort this loop is started or stopped.
- while (opModeInInit()) {
-
- // Send telemetry message to signify robot waiting;
- telemetry.addData("Status", "Ready to drive to white line."); //
-
- // Display the light level while we are waiting to start
- getBrightness();
- }
-
- // Start the robot moving forward, and then begin looking for a white line.
- leftDrive.setPower(APPROACH_SPEED);
- rightDrive.setPower(APPROACH_SPEED);
-
- // run until the white line is seen OR the driver presses STOP;
- while (opModeIsActive() && (getBrightness() < WHITE_THRESHOLD)) {
- sleep(5);
- }
-
- // Stop all motors
- leftDrive.setPower(0);
- rightDrive.setPower(0);
- }
-
- // to obtain reflected light, read the normalized values from the color sensor. Return the Alpha channel.
- double getBrightness() {
- NormalizedRGBA colors = colorSensor.getNormalizedColors();
- telemetry.addData("Light Level (0 to 1)", "%4.2f", colors.alpha);
- telemetry.update();
-
- return colors.alpha;
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotHardware.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotHardware.java
deleted file mode 100644
index b1c8de62..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotHardware.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/* Copyright (c) 2022 FIRST. 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.LinearOpMode;
-import com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.hardware.Servo;
-import com.qualcomm.robotcore.util.Range;
-
-/*
- * This file works in conjunction with the External Hardware Class sample called: ConceptExternalHardwareClass.java
- * Please read the explanations in that Sample about how to use this class definition.
- *
- * This file defines a Java Class that performs all the setup and configuration for a sample robot's hardware (motors and sensors).
- * It assumes three motors (left_drive, right_drive and arm) and two servos (left_hand and right_hand)
- *
- * This one file/class can be used by ALL of your OpModes without having to cut & paste the code each time.
- *
- * Where possible, the actual hardware objects are "abstracted" (or hidden) so the OpMode code just makes calls into the class,
- * rather than accessing the internal hardware directly. This is why the objects are declared "private".
- *
- * Use Android Studio to Copy this Class, and Paste it into your team's code folder with *exactly the same name*.
- *
- * Or... In OnBot Java, add a new file named RobotHardware.java, select this sample, and select Not an OpMode.
- * Also add a new OpMode, select the sample ConceptExternalHardwareClass.java, and select TeleOp.
- *
- */
-
-public class RobotHardware {
-
- /* Declare OpMode members. */
- private LinearOpMode myOpMode = null; // gain access to methods in the calling OpMode.
-
- // Define Motor and Servo objects (Make them private so they can't be accessed externally)
- private DcMotor leftDrive = null;
- private DcMotor rightDrive = null;
- private DcMotor armMotor = null;
- private Servo leftHand = null;
- private Servo rightHand = null;
-
- // Define Drive constants. Make them public so they CAN be used by the calling OpMode
- public static final double MID_SERVO = 0.5 ;
- public static final double HAND_SPEED = 0.02 ; // sets rate to move servo
- public static final double ARM_UP_POWER = 0.45 ;
- public static final double ARM_DOWN_POWER = -0.45 ;
-
- // Define a constructor that allows the OpMode to pass a reference to itself.
- public RobotHardware (LinearOpMode opmode) {
- myOpMode = opmode;
- }
-
- /**
- * Initialize all the robot's hardware.
- * This method must be called ONCE when the OpMode is initialized.
- *
- * All of the hardware devices are accessed via the hardware map, and initialized.
- */
- public void init() {
- // Define and Initialize Motors (note: need to use reference to actual OpMode).
- leftDrive = myOpMode.hardwareMap.get(DcMotor.class, "left_drive");
- rightDrive = myOpMode.hardwareMap.get(DcMotor.class, "right_drive");
- armMotor = myOpMode.hardwareMap.get(DcMotor.class, "arm");
-
- // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
- // Pushing the left stick forward MUST make robot go forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Gear Reduction or 90 Deg drives may require direction flips
- leftDrive.setDirection(DcMotor.Direction.REVERSE);
- rightDrive.setDirection(DcMotor.Direction.FORWARD);
-
- // If there are encoders connected, switch to RUN_USING_ENCODER mode for greater accuracy
- // leftDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- // rightDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
-
- // Define and initialize ALL installed servos.
- leftHand = myOpMode.hardwareMap.get(Servo.class, "left_hand");
- rightHand = myOpMode.hardwareMap.get(Servo.class, "right_hand");
- leftHand.setPosition(MID_SERVO);
- rightHand.setPosition(MID_SERVO);
-
- myOpMode.telemetry.addData(">", "Hardware Initialized");
- myOpMode.telemetry.update();
- }
-
- /**
- * Calculates the left/right motor powers required to achieve the requested
- * robot motions: Drive (Axial motion) and Turn (Yaw motion).
- * Then sends these power levels to the motors.
- *
- * @param Drive Fwd/Rev driving power (-1.0 to 1.0) +ve is forward
- * @param Turn Right/Left turning power (-1.0 to 1.0) +ve is CW
- */
- public void driveRobot(double Drive, double Turn) {
- // Combine drive and turn for blended motion.
- double left = Drive + Turn;
- double right = Drive - Turn;
-
- // Scale the values so neither exceed +/- 1.0
- double max = Math.max(Math.abs(left), Math.abs(right));
- if (max > 1.0)
- {
- left /= max;
- right /= max;
- }
-
- // Use existing function to drive both wheels.
- setDrivePower(left, right);
- }
-
- /**
- * Pass the requested wheel motor powers to the appropriate hardware drive motors.
- *
- * @param leftWheel Fwd/Rev driving power (-1.0 to 1.0) +ve is forward
- * @param rightWheel Fwd/Rev driving power (-1.0 to 1.0) +ve is forward
- */
- public void setDrivePower(double leftWheel, double rightWheel) {
- // Output the values to the motor drives.
- leftDrive.setPower(leftWheel);
- rightDrive.setPower(rightWheel);
- }
-
- /**
- * Pass the requested arm power to the appropriate hardware drive motor
- *
- * @param power driving power (-1.0 to 1.0)
- */
- public void setArmPower(double power) {
- armMotor.setPower(power);
- }
-
- /**
- * Send the two hand-servos to opposing (mirrored) positions, based on the passed offset.
- *
- * @param offset
- */
- public void setHandPositions(double offset) {
- offset = Range.clip(offset, -0.5, 0.5);
- leftHand.setPosition(MID_SERVO + offset);
- rightHand.setPosition(MID_SERVO - offset);
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotTeleopPOV_Linear.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotTeleopPOV_Linear.java
deleted file mode 100644
index af3840d3..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotTeleopPOV_Linear.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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 com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.hardware.Servo;
-import com.qualcomm.robotcore.util.Range;
-
-/*
- * This OpMode executes a POV Game style Teleop for a direct drive robot
- * The code is structured as a LinearOpMode
- *
- * In this mode the left stick moves the robot FWD and back, the Right stick turns left and right.
- * It raises and lowers the arm using the Gamepad Y and A buttons respectively.
- * It also opens and closes the claws slowly using the left and right Bumper buttons.
- *
- * 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="Robot: Teleop POV", group="Robot")
-@Disabled
-public class RobotTeleopPOV_Linear extends LinearOpMode {
-
- /* Declare OpMode members. */
- public DcMotor leftDrive = null;
- public DcMotor rightDrive = null;
- public DcMotor leftArm = null;
- public Servo leftClaw = null;
- public Servo rightClaw = null;
-
- double clawOffset = 0;
-
- public static final double MID_SERVO = 0.5 ;
- public static final double CLAW_SPEED = 0.02 ; // sets rate to move servo
- public static final double ARM_UP_POWER = 0.45 ;
- public static final double ARM_DOWN_POWER = -0.45 ;
-
- @Override
- public void runOpMode() {
- double left;
- double right;
- double drive;
- double turn;
- double max;
-
- // Define and Initialize Motors
- leftDrive = hardwareMap.get(DcMotor.class, "left_drive");
- rightDrive = hardwareMap.get(DcMotor.class, "right_drive");
- leftArm = hardwareMap.get(DcMotor.class, "left_arm");
-
- // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
- // Pushing the left stick forward MUST make robot go forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Gear Reduction or 90 Deg drives may require direction flips
- leftDrive.setDirection(DcMotor.Direction.REVERSE);
- rightDrive.setDirection(DcMotor.Direction.FORWARD);
-
- // If there are encoders connected, switch to RUN_USING_ENCODER mode for greater accuracy
- // leftDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- // rightDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
-
- // Define and initialize ALL installed servos.
- leftClaw = hardwareMap.get(Servo.class, "left_hand");
- rightClaw = hardwareMap.get(Servo.class, "right_hand");
- leftClaw.setPosition(MID_SERVO);
- rightClaw.setPosition(MID_SERVO);
-
- // Send telemetry message to signify robot waiting;
- telemetry.addData(">", "Robot Ready. Press START."); //
- telemetry.update();
-
- // Wait for the game to start (driver presses START)
- waitForStart();
-
- // run until the end of the match (driver presses STOP)
- while (opModeIsActive()) {
-
- // Run wheels in POV mode (note: The joystick goes negative when pushed forward, so negate it)
- // In this mode the Left stick moves the robot fwd and back, the Right stick turns left and right.
- // This way it's also easy to just drive straight, or just turn.
- drive = -gamepad1.left_stick_y;
- turn = gamepad1.right_stick_x;
-
- // Combine drive and turn for blended motion.
- left = drive + turn;
- right = drive - turn;
-
- // Normalize the values so neither exceed +/- 1.0
- max = Math.max(Math.abs(left), Math.abs(right));
- if (max > 1.0)
- {
- left /= max;
- right /= max;
- }
-
- // Output the safe vales to the motor drives.
- leftDrive.setPower(left);
- rightDrive.setPower(right);
-
- // Use gamepad left & right Bumpers to open and close the claw
- if (gamepad1.right_bumper)
- clawOffset += CLAW_SPEED;
- else if (gamepad1.left_bumper)
- clawOffset -= CLAW_SPEED;
-
- // Move both servos to new position. Assume servos are mirror image of each other.
- clawOffset = Range.clip(clawOffset, -0.5, 0.5);
- leftClaw.setPosition(MID_SERVO + clawOffset);
- rightClaw.setPosition(MID_SERVO - clawOffset);
-
- // Use gamepad buttons to move arm up (Y) and down (A)
- if (gamepad1.y)
- leftArm.setPower(ARM_UP_POWER);
- else if (gamepad1.a)
- leftArm.setPower(ARM_DOWN_POWER);
- else
- leftArm.setPower(0.0);
-
- // Send telemetry message to signify robot running;
- telemetry.addData("claw", "Offset = %.2f", clawOffset);
- telemetry.addData("left", "%.2f", left);
- telemetry.addData("right", "%.2f", right);
- telemetry.update();
-
- // Pace this loop so jaw action is reasonable speed.
- sleep(50);
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotTeleopTank_Iterative.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotTeleopTank_Iterative.java
deleted file mode 100644
index a622f27b..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotTeleopTank_Iterative.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.OpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.hardware.Servo;
-import com.qualcomm.robotcore.util.Range;
-
-/*
- * This OpMode executes a Tank Drive control TeleOp a direct drive robot
- * The code is structured as an Iterative OpMode
- *
- * In this mode, the left and right joysticks control the left and right motors respectively.
- * Pushing a joystick forward will make the attached motor drive forward.
- * It raises and lowers the claw using the Gamepad Y and A buttons respectively.
- * It also opens and closes the claws slowly using the left and right Bumper buttons.
- *
- * 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="Robot: Teleop Tank", group="Robot")
-@Disabled
-public class RobotTeleopTank_Iterative extends OpMode{
-
- /* Declare OpMode members. */
- public DcMotor leftDrive = null;
- public DcMotor rightDrive = null;
- public DcMotor leftArm = null;
- public Servo leftClaw = null;
- public Servo rightClaw = null;
-
- double clawOffset = 0;
-
- public static final double MID_SERVO = 0.5 ;
- public static final double CLAW_SPEED = 0.02 ; // sets rate to move servo
- public static final double ARM_UP_POWER = 0.50 ; // Run arm motor up at 50% power
- public static final double ARM_DOWN_POWER = -0.25 ; // Run arm motor down at -25% power
-
- /*
- * Code to run ONCE when the driver hits INIT
- */
- @Override
- public void init() {
- // Define and Initialize Motors
- leftDrive = hardwareMap.get(DcMotor.class, "left_drive");
- rightDrive = hardwareMap.get(DcMotor.class, "right_drive");
- leftArm = hardwareMap.get(DcMotor.class, "left_arm");
-
- // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
- // Pushing the left and right sticks forward MUST make robot go forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Gear Reduction or 90 Deg drives may require direction flips
- leftDrive.setDirection(DcMotor.Direction.REVERSE);
- rightDrive.setDirection(DcMotor.Direction.FORWARD);
-
- // If there are encoders connected, switch to RUN_USING_ENCODER mode for greater accuracy
- // leftDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- // rightDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
-
- // Define and initialize ALL installed servos.
- leftClaw = hardwareMap.get(Servo.class, "left_hand");
- rightClaw = hardwareMap.get(Servo.class, "right_hand");
- leftClaw.setPosition(MID_SERVO);
- rightClaw.setPosition(MID_SERVO);
-
- // Send telemetry message to signify robot waiting;
- telemetry.addData(">", "Robot Ready. Press START."); //
- }
-
- /*
- * Code to run REPEATEDLY after the driver hits INIT, but before they hit START
- */
- @Override
- public void init_loop() {
- }
-
- /*
- * Code to run ONCE when the driver hits START
- */
- @Override
- public void start() {
- }
-
- /*
- * Code to run REPEATEDLY after the driver hits START but before they hit STOP
- */
- @Override
- public void loop() {
- double left;
- double right;
-
- // Run wheels in tank mode (note: The joystick goes negative when pushed forward, so negate it)
- left = -gamepad1.left_stick_y;
- right = -gamepad1.right_stick_y;
-
- leftDrive.setPower(left);
- rightDrive.setPower(right);
-
- // Use gamepad left & right Bumpers to open and close the claw
- if (gamepad1.right_bumper)
- clawOffset += CLAW_SPEED;
- else if (gamepad1.left_bumper)
- clawOffset -= CLAW_SPEED;
-
- // Move both servos to new position. Assume servos are mirror image of each other.
- clawOffset = Range.clip(clawOffset, -0.5, 0.5);
- leftClaw.setPosition(MID_SERVO + clawOffset);
- rightClaw.setPosition(MID_SERVO - clawOffset);
-
- // Use gamepad buttons to move the arm up (Y) and down (A)
- if (gamepad1.y)
- leftArm.setPower(ARM_UP_POWER);
- else if (gamepad1.a)
- leftArm.setPower(ARM_DOWN_POWER);
- else
- leftArm.setPower(0.0);
-
- // Send telemetry message to signify robot running;
- telemetry.addData("claw", "Offset = %.2f", clawOffset);
- telemetry.addData("left", "%.2f", left);
- telemetry.addData("right", "%.2f", right);
- }
-
- /*
- * Code to run ONCE after the driver hits STOP
- */
- @Override
- public void stop() {
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SampleRevBlinkinLedDriver.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SampleRevBlinkinLedDriver.java
deleted file mode 100644
index bcf5b80e..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SampleRevBlinkinLedDriver.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 2018 Craig MacFarlane
- *
- * 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 Craig MacFarlane 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.rev.RevBlinkinLedDriver;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.OpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import org.firstinspires.ftc.robotcore.external.Telemetry;
-import org.firstinspires.ftc.robotcore.internal.system.Deadline;
-
-import java.util.concurrent.TimeUnit;
-
-/*
- * This OpMode demonstrates use of the REV Robotics Blinkin LED Driver.
- * AUTO mode cycles through all of the patterns.
- * MANUAL mode allows the user to manually change patterns using the
- * left and right bumpers of a gamepad.
- *
- * Configure the driver on a servo port, and name it "blinkin".
- *
- * Displays the first pattern upon init.
- */
-@TeleOp(name="BlinkinExample")
-@Disabled
-public class SampleRevBlinkinLedDriver extends OpMode {
-
- /*
- * Change the pattern every 10 seconds in AUTO mode.
- */
- private final static int LED_PERIOD = 10;
-
- /*
- * Rate limit gamepad button presses to every 500ms.
- */
- private final static int GAMEPAD_LOCKOUT = 500;
-
- RevBlinkinLedDriver blinkinLedDriver;
- RevBlinkinLedDriver.BlinkinPattern pattern;
-
- Telemetry.Item patternName;
- Telemetry.Item display;
- DisplayKind displayKind;
- Deadline ledCycleDeadline;
- Deadline gamepadRateLimit;
-
- protected enum DisplayKind {
- MANUAL,
- AUTO
- }
-
- @Override
- public void init()
- {
- displayKind = DisplayKind.AUTO;
-
- blinkinLedDriver = hardwareMap.get(RevBlinkinLedDriver.class, "blinkin");
- pattern = RevBlinkinLedDriver.BlinkinPattern.RAINBOW_RAINBOW_PALETTE;
- blinkinLedDriver.setPattern(pattern);
-
- display = telemetry.addData("Display Kind: ", displayKind.toString());
- patternName = telemetry.addData("Pattern: ", pattern.toString());
-
- ledCycleDeadline = new Deadline(LED_PERIOD, TimeUnit.SECONDS);
- gamepadRateLimit = new Deadline(GAMEPAD_LOCKOUT, TimeUnit.MILLISECONDS);
- }
-
- @Override
- public void loop()
- {
- handleGamepad();
-
- if (displayKind == DisplayKind.AUTO) {
- doAutoDisplay();
- } else {
- /*
- * MANUAL mode: Nothing to do, setting the pattern as a result of a gamepad event.
- */
- }
- }
-
- /*
- * handleGamepad
- *
- * Responds to a gamepad button press. Demonstrates rate limiting for
- * button presses. If loop() is called every 10ms and and you don't rate
- * limit, then any given button press may register as multiple button presses,
- * which in this application is problematic.
- *
- * A: Manual mode, Right bumper displays the next pattern, left bumper displays the previous pattern.
- * B: Auto mode, pattern cycles, changing every LED_PERIOD seconds.
- */
- protected void handleGamepad()
- {
- if (!gamepadRateLimit.hasExpired()) {
- return;
- }
-
- if (gamepad1.a) {
- setDisplayKind(DisplayKind.MANUAL);
- gamepadRateLimit.reset();
- } else if (gamepad1.b) {
- setDisplayKind(DisplayKind.AUTO);
- gamepadRateLimit.reset();
- } else if ((displayKind == DisplayKind.MANUAL) && (gamepad1.left_bumper)) {
- pattern = pattern.previous();
- displayPattern();
- gamepadRateLimit.reset();
- } else if ((displayKind == DisplayKind.MANUAL) && (gamepad1.right_bumper)) {
- pattern = pattern.next();
- displayPattern();
- gamepadRateLimit.reset();
- }
- }
-
- protected void setDisplayKind(DisplayKind displayKind)
- {
- this.displayKind = displayKind;
- display.setValue(displayKind.toString());
- }
-
- protected void doAutoDisplay()
- {
- if (ledCycleDeadline.hasExpired()) {
- pattern = pattern.next();
- displayPattern();
- ledCycleDeadline.reset();
- }
- }
-
- protected void displayPattern()
- {
- blinkinLedDriver.setPattern(pattern);
- patternName.setValue(pattern.toString());
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMU.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMU.java
deleted file mode 100644
index 405da1e9..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMU.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.bosch.BNO055IMU;
-import com.qualcomm.hardware.bosch.JustLoggingAccelerationIntegrator;
-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.Func;
-import org.firstinspires.ftc.robotcore.external.navigation.Acceleration;
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-import org.firstinspires.ftc.robotcore.external.navigation.AxesOrder;
-import org.firstinspires.ftc.robotcore.external.navigation.AxesReference;
-import org.firstinspires.ftc.robotcore.external.navigation.Orientation;
-import org.firstinspires.ftc.robotcore.external.navigation.Position;
-import org.firstinspires.ftc.robotcore.external.navigation.Velocity;
-
-import java.util.Locale;
-
-/*
- * This OpMode gives a short demo on how to use the BNO055 Inertial Motion Unit (IMU) from AdaFruit.
- *
- * Note: this is a Legacy example that will not work with newer Control/Expansion Hubs that use a different IMU
- * Please use the new SensorIMUOrthogonal or SensorIMUNonOrthogonal samples for a more universal IMU interface.
- *
- * 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
- *
- * @see Adafruit IMU
- */
-@TeleOp(name = "Sensor: BNO055 IMU", group = "Sensor")
-@Disabled // Comment this out to add to the OpMode list
-public class SensorBNO055IMU extends LinearOpMode
- {
- //----------------------------------------------------------------------------------------------
- // State
- //----------------------------------------------------------------------------------------------
-
- // The IMU sensor object
- BNO055IMU imu;
-
- // State used for updating telemetry
- Orientation angles;
- Acceleration gravity;
-
- //----------------------------------------------------------------------------------------------
- // Main logic
- //----------------------------------------------------------------------------------------------
-
- @Override public void runOpMode() {
-
- // Set up the parameters with which we will use our IMU. Note that integration
- // algorithm here just reports accelerations to the logcat log; it doesn't actually
- // provide positional information.
- BNO055IMU.Parameters parameters = new BNO055IMU.Parameters();
- parameters.angleUnit = BNO055IMU.AngleUnit.DEGREES;
- parameters.accelUnit = BNO055IMU.AccelUnit.METERS_PERSEC_PERSEC;
- parameters.calibrationDataFile = "BNO055IMUCalibration.json"; // see the calibration sample OpMode
- parameters.loggingEnabled = true;
- parameters.loggingTag = "IMU";
- parameters.accelerationIntegrationAlgorithm = new JustLoggingAccelerationIntegrator();
-
- // Retrieve and initialize the IMU. We expect the IMU to be attached to an I2C port
- // on a Core Device Interface Module, configured to be a sensor of type "AdaFruit IMU",
- // and named "imu".
- imu = hardwareMap.get(BNO055IMU.class, "imu");
- imu.initialize(parameters);
-
- // Set up our telemetry dashboard
- composeTelemetry();
-
- // Wait until we're told to go
- waitForStart();
-
- // Start the logging of measured acceleration
- imu.startAccelerationIntegration(new Position(), new Velocity(), 1000);
-
- // Loop and update the dashboard
- while (opModeIsActive()) {
- telemetry.update();
- }
- }
-
- //----------------------------------------------------------------------------------------------
- // Telemetry Configuration
- //----------------------------------------------------------------------------------------------
-
- void composeTelemetry() {
-
- // At the beginning of each telemetry update, grab a bunch of data
- // from the IMU that we will then display in separate lines.
- telemetry.addAction(new Runnable() { @Override public void run()
- {
- // Acquiring the angles is relatively expensive; we don't want
- // to do that in each of the three items that need that info, as that's
- // three times the necessary expense.
- angles = imu.getAngularOrientation(AxesReference.INTRINSIC, AxesOrder.ZYX, AngleUnit.DEGREES);
- gravity = imu.getGravity();
- }
- });
-
- telemetry.addLine()
- .addData("status", new Func() {
- @Override public String value() {
- return imu.getSystemStatus().toShortString();
- }
- })
- .addData("calib", new Func() {
- @Override public String value() {
- return imu.getCalibrationStatus().toString();
- }
- });
-
- telemetry.addLine()
- .addData("heading", new Func() {
- @Override public String value() {
- return formatAngle(angles.angleUnit, angles.firstAngle);
- }
- })
- .addData("roll", new Func() {
- @Override public String value() {
- return formatAngle(angles.angleUnit, angles.secondAngle);
- }
- })
- .addData("pitch", new Func() {
- @Override public String value() {
- return formatAngle(angles.angleUnit, angles.thirdAngle);
- }
- });
-
- telemetry.addLine()
- .addData("grvty", new Func() {
- @Override public String value() {
- return gravity.toString();
- }
- })
- .addData("mag", new Func() {
- @Override public String value() {
- return String.format(Locale.getDefault(), "%.3f",
- Math.sqrt(gravity.xAccel*gravity.xAccel
- + gravity.yAccel*gravity.yAccel
- + gravity.zAccel*gravity.zAccel));
- }
- });
- }
-
- //----------------------------------------------------------------------------------------------
- // Formatting
- //----------------------------------------------------------------------------------------------
-
- String formatAngle(AngleUnit angleUnit, double angle) {
- return formatDegrees(AngleUnit.DEGREES.fromUnit(angleUnit, angle));
- }
-
- String formatDegrees(double degrees){
- return String.format(Locale.getDefault(), "%.1f", AngleUnit.DEGREES.normalize(degrees));
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMUCalibration.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMUCalibration.java
deleted file mode 100644
index 93f1789d..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMUCalibration.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.bosch.BNO055IMU;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.util.ReadWriteFile;
-import org.firstinspires.ftc.robotcore.external.Func;
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-import org.firstinspires.ftc.robotcore.external.navigation.AxesOrder;
-import org.firstinspires.ftc.robotcore.external.navigation.AxesReference;
-import org.firstinspires.ftc.robotcore.external.navigation.Orientation;
-import org.firstinspires.ftc.robotcore.internal.system.AppUtil;
-
-import java.io.File;
-import java.util.Locale;
-
-/*
- * This OpMode calibrates a BNO055 IMU per
- * "Section 3.11 Calibration" of the BNO055 specification.
- *
- * Note: this is a Legacy example that will not work with newer Control/Expansion Hubs that use a different IMU
- * Please use the new SensorIMUOrthogonal or SensorIMUNonOrthogonal samples for a more universal IMU interface.
- *
- * Manual calibration of the IMU is definitely NOT necessary: except for the magnetometer (which is not used by the
- * default "IMU" SensorMode), the BNO055 is internally self-calibrating and thus can be very successfully used without
- * manual intervention. That said, performing a one-time calibration, saving the results persistently, then loading them
- * again at each run can help reduce the time that automatic calibration requires.
- *
- * This summary of the calibration process from Intel is informative:
- * http://iotdk.intel.com/docs/master/upm/classupm_1_1_b_n_o055.html
- *
- * "This device requires calibration in order to operate accurately. [...] Calibration data is
- * lost on a power cycle. See one of the examples for a description of how to calibrate the device,
- * but in essence:
- *
- * There is a calibration status register available [...] that returns the calibration status
- * of the accelerometer (ACC), magnetometer (MAG), gyroscope (GYR), and overall system (SYS).
- * Each of these values range from 0 (uncalibrated) to 3 (fully calibrated). Calibration [ideally]
- * involves certain motions to get all 4 values at 3. The motions are as follows (though see the
- * datasheet for more information):
- *
- * 1. GYR: Simply let the sensor sit flat for a few seconds.
- * 2. ACC: Move the sensor in various positions. Start flat, then rotate slowly by 45
- * degrees, hold for a few seconds, then continue rotating another 45 degrees and
- * hold, etc. 6 or more movements of this type may be required. You can move through
- * any axis you desire, but make sure that the device is lying at least once
- * perpendicular to the x, y, and z axis.
- * 3. MAG: Move slowly in a figure 8 pattern in the air, until the calibration values reaches 3.
- * 4. SYS: This will usually reach 3 when the other items have also reached 3. If not, continue
- * slowly moving the device though various axes until it does."
- *
- * To calibrate the IMU, run this sample OpMode with a gamepad attached to the driver station.
- * Once the IMU has reached sufficient calibration as reported on telemetry, press the 'A'
- * button on the gamepad to write the calibration to a file. That file can then be indicated
- * later when running an OpMode which uses the IMU.
- *
- * Note: if your intended uses of the IMU do not include use of all its sensors (for example,
- * you might not use the magnetometer), then it makes little sense for you to wait for full
- * calibration of the sensors you are not using before saving the calibration data. Indeed,
- * it appears that in a SensorMode that doesn't use the magnetometer (for example), the
- * magnetometer cannot actually be calibrated.
- *
- * References:
- * The AdafruitBNO055IMU Javadoc
- * The BNO055IMU.Parameters.calibrationDataFile Javadoc
- * The BNO055 product page: https://www.bosch-sensortec.com/bst/products/all_products/bno055
- * The BNO055 datasheet: https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bno055-ds000.pdf
- */
-@TeleOp(name = "Sensor: BNO055 IMU Calibration", group = "Sensor")
-@Disabled // Uncomment this to add to the OpMode list
-public class SensorBNO055IMUCalibration extends LinearOpMode
- {
- //----------------------------------------------------------------------------------------------
- // State
- //----------------------------------------------------------------------------------------------
-
- // Our sensors, motors, and other devices go here, along with other long term state
- BNO055IMU imu;
-
- // State used for updating telemetry
- Orientation angles;
-
- //----------------------------------------------------------------------------------------------
- // Main logic
- //----------------------------------------------------------------------------------------------
-
- @Override public void runOpMode() {
-
- telemetry.log().setCapacity(12);
- telemetry.log().add("");
- telemetry.log().add("Please refer to the calibration instructions");
- telemetry.log().add("contained in the Adafruit IMU calibration");
- telemetry.log().add("sample OpMode.");
- telemetry.log().add("");
- telemetry.log().add("When sufficient calibration has been reached,");
- telemetry.log().add("press the 'A' button to write the current");
- telemetry.log().add("calibration data to a file.");
- telemetry.log().add("");
-
- // We are expecting the IMU to be attached to an I2C port on a Core Device Interface Module and named "imu".
- BNO055IMU.Parameters parameters = new BNO055IMU.Parameters();
- parameters.loggingEnabled = true;
- parameters.loggingTag = "IMU";
- imu = hardwareMap.get(BNO055IMU.class, "imu");
- imu.initialize(parameters);
-
- composeTelemetry();
- telemetry.log().add("Waiting for start...");
-
- // Wait until we're told to go
- while (!isStarted()) {
- telemetry.update();
- idle();
- }
-
- telemetry.log().add("...started...");
-
- while (opModeIsActive()) {
-
- if (gamepad1.a) {
-
- // Get the calibration data
- BNO055IMU.CalibrationData calibrationData = imu.readCalibrationData();
-
- // Save the calibration data to a file. You can choose whatever file
- // name you wish here, but you'll want to indicate the same file name
- // when you initialize the IMU in an OpMode in which it is used. If you
- // have more than one IMU on your robot, you'll of course want to use
- // different configuration file names for each.
- String filename = "AdafruitIMUCalibration.json";
- File file = AppUtil.getInstance().getSettingsFile(filename);
- ReadWriteFile.writeFile(file, calibrationData.serialize());
- telemetry.log().add("saved to '%s'", filename);
-
- // Wait for the button to be released
- while (gamepad1.a) {
- telemetry.update();
- idle();
- }
- }
-
- telemetry.update();
- }
- }
-
- void composeTelemetry() {
-
- // At the beginning of each telemetry update, grab a bunch of data
- // from the IMU that we will then display in separate lines.
- telemetry.addAction(new Runnable() { @Override public void run()
- {
- // Acquiring the angles is relatively expensive; we don't want
- // to do that in each of the three items that need that info, as that's
- // three times the necessary expense.
- angles = imu.getAngularOrientation(AxesReference.INTRINSIC, AxesOrder.ZYX, AngleUnit.DEGREES);
- }
- });
-
- telemetry.addLine()
- .addData("status", new Func() {
- @Override public String value() {
- return imu.getSystemStatus().toShortString();
- }
- })
- .addData("calib", new Func() {
- @Override public String value() {
- return imu.getCalibrationStatus().toString();
- }
- });
-
- telemetry.addLine()
- .addData("heading", new Func() {
- @Override public String value() {
- return formatAngle(angles.angleUnit, angles.firstAngle);
- }
- })
- .addData("roll", new Func() {
- @Override public String value() {
- return formatAngle(angles.angleUnit, angles.secondAngle);
- }
- })
- .addData("pitch", new Func() {
- @Override public String value() {
- return formatAngle(angles.angleUnit, angles.thirdAngle);
- }
- });
- }
-
- //----------------------------------------------------------------------------------------------
- // Formatting
- //----------------------------------------------------------------------------------------------
-
- String formatAngle(AngleUnit angleUnit, double angle) {
- return formatDegrees(AngleUnit.DEGREES.fromUnit(angleUnit, angle));
- }
-
- String formatDegrees(double degrees){
- return String.format(Locale.getDefault(), "%.1f", AngleUnit.DEGREES.normalize(degrees));
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorColor.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorColor.java
deleted file mode 100644
index 7546c9de..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorColor.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/* Copyright (c) 2017-2020 FIRST. 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 android.app.Activity;
-import android.graphics.Color;
-import android.view.View;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.DistanceSensor;
-import com.qualcomm.robotcore.hardware.NormalizedColorSensor;
-import com.qualcomm.robotcore.hardware.NormalizedRGBA;
-import com.qualcomm.robotcore.hardware.SwitchableLight;
-import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit;
-
-/*
- * This OpMode shows how to use a color sensor in a generic
- * way, regardless of which particular make or model of color sensor is used. The OpMode
- * assumes that the color sensor is configured with a name of "sensor_color".
- *
- * There will be some variation in the values measured depending on the specific sensor you are using.
- *
- * You can increase the gain (a multiplier to make the sensor report higher values) by holding down
- * the A button on the gamepad, and decrease the gain by holding down the B button on the gamepad.
- *
- * If the color sensor has a light which is controllable from software, you can use the X button on
- * the gamepad to toggle the light on and off. The REV sensors don't support this, but instead have
- * a physical switch on them to turn the light on and off, beginning with REV Color Sensor V2.
- *
- * If the color sensor also supports short-range distance measurements (usually via an infrared
- * proximity sensor), the reported distance will be written to telemetry. As of September 2020,
- * the only color sensors that support this are the ones from REV Robotics. These infrared proximity
- * sensor measurements are only useful at very small distances, and are sensitive to ambient light
- * and surface reflectivity. You should use a different sensor if you need precise distance measurements.
- *
- * 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 = "Sensor: Color", group = "Sensor")
-@Disabled
-public class SensorColor extends LinearOpMode {
-
- /** The colorSensor field will contain a reference to our color sensor hardware object */
- NormalizedColorSensor colorSensor;
-
- /** The relativeLayout field is used to aid in providing interesting visual feedback
- * in this sample application; you probably *don't* need this when you use a color sensor on your
- * robot. Note that you won't see anything change on the Driver Station, only on the Robot Controller. */
- View relativeLayout;
-
- /*
- * The runOpMode() method is the root of this OpMode, as it is in all LinearOpModes.
- * Our implementation here, though is a bit unusual: we've decided to put all the actual work
- * in the runSample() method rather than directly in runOpMode() itself. The reason we do that is
- * that in this sample we're changing the background color of the robot controller screen as the
- * OpMode runs, and we want to be able to *guarantee* that we restore it to something reasonable
- * and palatable when the OpMode ends. The simplest way to do that is to use a try...finally
- * block around the main, core logic, and an easy way to make that all clear was to separate
- * the former from the latter in separate methods.
- */
- @Override public void runOpMode() {
-
- // Get a reference to the RelativeLayout so we can later change the background
- // color of the Robot Controller app to match the hue detected by the RGB sensor.
- int relativeLayoutId = hardwareMap.appContext.getResources().getIdentifier("RelativeLayout", "id", hardwareMap.appContext.getPackageName());
- relativeLayout = ((Activity) hardwareMap.appContext).findViewById(relativeLayoutId);
-
- try {
- runSample(); // actually execute the sample
- } finally {
- // On the way out, *guarantee* that the background is reasonable. It doesn't actually start off
- // as pure white, but it's too much work to dig out what actually was used, and this is good
- // enough to at least make the screen reasonable again.
- // Set the panel back to the default color
- relativeLayout.post(new Runnable() {
- public void run() {
- relativeLayout.setBackgroundColor(Color.WHITE);
- }
- });
- }
- }
-
- protected void runSample() {
- // You can give the sensor a gain value, will be multiplied by the sensor's raw value before the
- // normalized color values are calculated. Color sensors (especially the REV Color Sensor V3)
- // can give very low values (depending on the lighting conditions), which only use a small part
- // of the 0-1 range that is available for the red, green, and blue values. In brighter conditions,
- // you should use a smaller gain than in dark conditions. If your gain is too high, all of the
- // colors will report at or near 1, and you won't be able to determine what color you are
- // actually looking at. For this reason, it's better to err on the side of a lower gain
- // (but always greater than or equal to 1).
- float gain = 2;
-
- // Once per loop, we will update this hsvValues array. The first element (0) will contain the
- // hue, the second element (1) will contain the saturation, and the third element (2) will
- // contain the value. See http://web.archive.org/web/20190311170843/https://infohost.nmt.edu/tcc/help/pubs/colortheory/web/hsv.html
- // for an explanation of HSV color.
- final float[] hsvValues = new float[3];
-
- // xButtonPreviouslyPressed and xButtonCurrentlyPressed keep track of the previous and current
- // state of the X button on the gamepad
- boolean xButtonPreviouslyPressed = false;
- boolean xButtonCurrentlyPressed = false;
-
- // Get a reference to our sensor object. It's recommended to use NormalizedColorSensor over
- // ColorSensor, because NormalizedColorSensor consistently gives values between 0 and 1, while
- // the values you get from ColorSensor are dependent on the specific sensor you're using.
- colorSensor = hardwareMap.get(NormalizedColorSensor.class, "sensor_color");
-
- // If possible, turn the light on in the beginning (it might already be on anyway,
- // we just make sure it is if we can).
- if (colorSensor instanceof SwitchableLight) {
- ((SwitchableLight)colorSensor).enableLight(true);
- }
-
- // Wait for the start button to be pressed.
- waitForStart();
-
- // Loop until we are asked to stop
- while (opModeIsActive()) {
- // Explain basic gain information via telemetry
- telemetry.addLine("Hold the A button on gamepad 1 to increase gain, or B to decrease it.\n");
- telemetry.addLine("Higher gain values mean that the sensor will report larger numbers for Red, Green, and Blue, and Value\n");
-
- // Update the gain value if either of the A or B gamepad buttons is being held
- if (gamepad1.a) {
- // Only increase the gain by a small amount, since this loop will occur multiple times per second.
- gain += 0.005;
- } else if (gamepad1.b && gain > 1) { // A gain of less than 1 will make the values smaller, which is not helpful.
- gain -= 0.005;
- }
-
- // Show the gain value via telemetry
- telemetry.addData("Gain", gain);
-
- // Tell the sensor our desired gain value (normally you would do this during initialization,
- // not during the loop)
- colorSensor.setGain(gain);
-
- // Check the status of the X button on the gamepad
- xButtonCurrentlyPressed = gamepad1.x;
-
- // If the button state is different than what it was, then act
- if (xButtonCurrentlyPressed != xButtonPreviouslyPressed) {
- // If the button is (now) down, then toggle the light
- if (xButtonCurrentlyPressed) {
- if (colorSensor instanceof SwitchableLight) {
- SwitchableLight light = (SwitchableLight)colorSensor;
- light.enableLight(!light.isLightOn());
- }
- }
- }
- xButtonPreviouslyPressed = xButtonCurrentlyPressed;
-
- // Get the normalized colors from the sensor
- NormalizedRGBA colors = colorSensor.getNormalizedColors();
-
- /* Use telemetry to display feedback on the driver station. We show the red, green, and blue
- * normalized values from the sensor (in the range of 0 to 1), as well as the equivalent
- * HSV (hue, saturation and value) values. See http://web.archive.org/web/20190311170843/https://infohost.nmt.edu/tcc/help/pubs/colortheory/web/hsv.html
- * for an explanation of HSV color. */
-
- // Update the hsvValues array by passing it to Color.colorToHSV()
- Color.colorToHSV(colors.toColor(), hsvValues);
-
- telemetry.addLine()
- .addData("Red", "%.3f", colors.red)
- .addData("Green", "%.3f", colors.green)
- .addData("Blue", "%.3f", colors.blue);
- telemetry.addLine()
- .addData("Hue", "%.3f", hsvValues[0])
- .addData("Saturation", "%.3f", hsvValues[1])
- .addData("Value", "%.3f", hsvValues[2]);
- telemetry.addData("Alpha", "%.3f", colors.alpha);
-
- /* If this color sensor also has a distance sensor, display the measured distance.
- * Note that the reported distance is only useful at very close range, and is impacted by
- * ambient light and surface reflectivity. */
- if (colorSensor instanceof DistanceSensor) {
- telemetry.addData("Distance (cm)", "%.3f", ((DistanceSensor) colorSensor).getDistance(DistanceUnit.CM));
- }
-
- telemetry.update();
-
- // Change the Robot Controller's background color to match the color detected by the color sensor.
- relativeLayout.post(new Runnable() {
- public void run() {
- relativeLayout.setBackgroundColor(Color.HSVToColor(hsvValues));
- }
- });
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorDigitalTouch.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorDigitalTouch.java
deleted file mode 100644
index 44c3ca9c..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorDigitalTouch.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Copyright (c) 2024 FIRST. 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 com.qualcomm.robotcore.hardware.DigitalChannel;
-
-/*
- * This OpMode demonstrates how to use a digital channel.
- *
- * The OpMode assumes that the digital channel is configured with a name of "digitalTouch".
- *
- * 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 = "Sensor: digital channel", group = "Sensor")
-@Disabled
-public class SensorDigitalTouch extends LinearOpMode {
- DigitalChannel digitalTouch; // Digital channel Object
-
- @Override
- public void runOpMode() {
-
- // get a reference to our touchSensor object.
- digitalTouch = hardwareMap.get(DigitalChannel.class, "digitalTouch");
-
- digitalTouch.setMode(DigitalChannel.Mode.INPUT);
- telemetry.addData("DigitalTouchSensorExample", "Press start to continue...");
- telemetry.update();
-
- // wait for the start button to be pressed.
- waitForStart();
-
- // while the OpMode is active, loop and read the digital channel.
- // Note we use opModeIsActive() as our loop condition because it is an interruptible method.
- while (opModeIsActive()) {
-
- // button is pressed if value returned is LOW or false.
- // send the info back to driver station using telemetry function.
- if (digitalTouch.getState() == false) {
- telemetry.addData("Button", "PRESSED");
- } else {
- telemetry.addData("Button", "NOT PRESSED");
- }
-
- telemetry.update();
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorHuskyLens.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorHuskyLens.java
deleted file mode 100644
index af7ca552..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorHuskyLens.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
-Copyright (c) 2023 FIRST
-
-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.dfrobot.HuskyLens;
-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.internal.system.Deadline;
-
-import java.util.concurrent.TimeUnit;
-
-/*
- * This OpMode illustrates how to use the DFRobot HuskyLens.
- *
- * The HuskyLens is a Vision Sensor with a built-in object detection model. It 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
- * 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
- * of objects by changing the algorithm. It assumes that the HuskyLens is configured with
- * a name of "huskylens".
- *
- * 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 = "Sensor: HuskyLens", group = "Sensor")
-@Disabled
-public class SensorHuskyLens extends LinearOpMode {
-
- private final int READ_PERIOD = 1;
-
- private HuskyLens huskyLens;
-
- @Override
- public void runOpMode()
- {
- huskyLens = hardwareMap.get(HuskyLens.class, "huskylens");
-
- /*
- * This sample rate limits the reads solely to allow a user time to observe
- * what is happening on the Driver Station telemetry. Typical applications
- * would not likely rate limit.
- */
- Deadline rateLimit = new Deadline(READ_PERIOD, TimeUnit.SECONDS);
-
- /*
- * Immediately expire so that the first time through we'll do the read.
- */
- rateLimit.expire();
-
- /*
- * Basic check to see if the device is alive and communicating. This is not
- * technically necessary here as the HuskyLens class does this in its
- * doInitialization() method which is called when the device is pulled out of
- * the hardware map. However, sometimes it's unclear why a device reports as
- * failing on initialization. In the case of this device, it's because the
- * call to knock() failed.
- */
- if (!huskyLens.knock()) {
- telemetry.addData(">>", "Problem communicating with " + huskyLens.getDeviceName());
- } else {
- telemetry.addData(">>", "Press start to continue");
- }
-
- /*
- * The device uses the concept of an algorithm to determine what types of
- * objects it will look for and/or what mode it is in. The algorithm may be
- * selected using the scroll wheel on the device, or via software as shown in
- * the call to selectAlgorithm().
- *
- * The SDK itself does not assume that the user wants a particular algorithm on
- * startup, and hence does not set an algorithm.
- *
- * 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
- * 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);
-
- telemetry.update();
- waitForStart();
-
- /*
- * Looking for AprilTags per the call to selectAlgorithm() above. A handy grid
- * for testing may be found at https://wiki.dfrobot.com/HUSKYLENS_V1.0_SKU_SEN0305_SEN0336#target_20.
- *
- * Note again that the device only recognizes the 36h11 family of tags out of the box.
- */
- while(opModeIsActive()) {
- if (!rateLimit.hasExpired()) {
- continue;
- }
- rateLimit.reset();
-
- /*
- * All algorithms, except for LINE_TRACKING, return a list of Blocks where a
- * Block represents the outline of a recognized object along with its ID number.
- * ID numbers allow you to identify what the device saw. See the HuskyLens documentation
- * referenced in the header comment above for more information on IDs and how to
- * assign them to objects.
- *
- * Returns an empty array if no objects are seen.
- */
- HuskyLens.Block[] blocks = huskyLens.blocks();
- telemetry.addData("Block count", blocks.length);
- for (int i = 0; i < blocks.length; i++) {
- 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();
- }
- }
-}
\ No newline at end of file
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUNonOrthogonal.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUNonOrthogonal.java
deleted file mode 100644
index 70bc8d4a..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUNonOrthogonal.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/* Copyright (c) 2022 FIRST. 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.rev.RevHubOrientationOnRobot;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.IMU;
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-import org.firstinspires.ftc.robotcore.external.navigation.AngularVelocity;
-import org.firstinspires.ftc.robotcore.external.navigation.Orientation;
-import org.firstinspires.ftc.robotcore.external.navigation.YawPitchRollAngles;
-
-import static com.qualcomm.hardware.rev.RevHubOrientationOnRobot.xyzOrientation;
-
-/*
- * This OpMode shows how to use the new universal IMU interface. This
- * interface may be used with the BNO055 IMU or the BHI260 IMU. It assumes that an IMU is configured
- * on the robot with the name "imu".
- *
- * The sample will display the current Yaw, Pitch and Roll of the robot.
- * With the correct orientation parameters selected, pitch/roll/yaw should act as follows:
- * Pitch value should INCREASE as the robot is tipped UP at the front. (Rotation about X)
- * Roll value should INCREASE as the robot is tipped UP at the left side. (Rotation about Y)
- * Yaw value should INCREASE as the robot is rotated Counter Clockwise. (Rotation about Z)
- *
- * The yaw can be reset (to zero) by pressing the Y button on the gamepad (Triangle on a PS4 controller)
- *
- * This specific sample DOES NOT assume that the Hub is mounted on one of the three orthogonal
- * 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
- * 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
- * that transform a "Default" Hub orientation into your desired orientation. That is what is
- * illustrated here.
- *
- * 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.
- *
- * Finally, edit this OpMode to use at least one angle around an axis to orient your Hub.
- */
-@TeleOp(name = "Sensor: IMU Non-Orthogonal", group = "Sensor")
-@Disabled // Comment this out to add to the OpMode list
-public class SensorIMUNonOrthogonal extends LinearOpMode
-{
- // The IMU sensor object
- IMU imu;
-
- //----------------------------------------------------------------------------------------------
- // Main logic
- //----------------------------------------------------------------------------------------------
-
- @Override public void runOpMode() throws InterruptedException {
-
- // Retrieve and initialize the IMU.
- // This sample expects the IMU to be in a REV Hub and named "imu".
- imu = hardwareMap.get(IMU.class, "imu");
-
- /* Define how the hub is mounted to the robot to get the correct Yaw, Pitch and Roll values.
- *
- * You can apply up to three axis rotations to orient your Hub according to how it's mounted on the robot.
- *
- * The starting point for these rotations is the "Default" Hub orientation, which is:
- * 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.
- *
- * 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.
- * 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
- * used for the results the IMU gives us. In the starting orientation, the Hub axes are
- * aligned with the Robot Coordinate System:
- *
- * X Axis: Starting at Center of Hub, pointing out towards I2C connectors
- * Y Axis: Starting at Center of Hub, pointing out towards USB connectors
- * Z Axis: Starting at Center of Hub, pointing Up through LOGO
- *
- * Positive rotation is defined by right-hand rule with thumb pointing in +ve direction on axis.
- *
- * Some examples.
- *
- * ----------------------------------------------------------------------------------------------------------------------------------
- * Example A) Assume that the hub is mounted on a sloped plate at the back of the robot, with the USB ports coming out the top of the hub.
- * The plate is tilted UP 60 degrees from horizontal.
- *
- * To get the "Default" hub into this configuration you would just need a single rotation.
- * 1) Rotate the Hub +60 degrees around the X axis to tilt up the front edge.
- * 2) No rotation around the Y or Z axes.
- *
- * So the X,Y,Z rotations would be 60,0,0
- *
- * ----------------------------------------------------------------------------------------------------------------------------------
- * Example B) Assume that the hub is laying flat on the chassis, but it has been twisted 30 degrees towards the right front wheel to make
- * the USB cable accessible.
- *
- * 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.
- * 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
- *
- * ----------------------------------------------------------------------------------------------------------------------------------
- * Example C) Assume that the hub is mounted on a vertical plate on the right side of the robot, with the Logo facing out, and the
- * Hub rotated so that the USB ports are facing down 30 degrees towards the back wheels of the robot.
- *
- * To get the "Default" hub into this configuration will require several rotations.
- * 1) Rotate the hub +90 degrees around the X axis to get it standing upright with the logo pointing backwards on the robot
- * 2) Next, rotate the hub +90 around the Y axis to get it facing to the right.
- * 3) Finally rotate the hub +120 degrees around the Z axis to take the USB ports from vertical to sloping down 30 degrees and
- * facing towards the back of the robot.
- *
- * So the X,Y,Z rotations would be 90,90,120
- */
-
- // The next three lines define the desired axis rotations.
- // To Do: EDIT these values to match YOUR mounting configuration.
- double xRotation = 0; // enter the desired X rotation angle here.
- double yRotation = 0; // enter the desired Y rotation angle here.
- double zRotation = 0; // enter the desired Z rotation angle here.
-
- Orientation hubRotation = xyzOrientation(xRotation, yRotation, zRotation);
-
- // Now initialize the IMU with this mounting orientation
- RevHubOrientationOnRobot orientationOnRobot = new RevHubOrientationOnRobot(hubRotation);
- imu.initialize(new IMU.Parameters(orientationOnRobot));
-
- // Loop and update the dashboard
- while (!isStopRequested()) {
- telemetry.addData("Hub orientation", "X=%.1f, Y=%.1f, Z=%.1f \n", xRotation, yRotation, zRotation);
-
- // Check to see if heading reset is requested
- if (gamepad1.y) {
- telemetry.addData("Yaw", "Resetting\n");
- imu.resetYaw();
- } else {
- telemetry.addData("Yaw", "Press Y (triangle) on Gamepad to reset\n");
- }
-
- // Retrieve Rotational Angles and Velocities
- YawPitchRollAngles orientation = imu.getRobotYawPitchRollAngles();
- AngularVelocity angularVelocity = imu.getRobotAngularVelocity(AngleUnit.DEGREES);
-
- telemetry.addData("Yaw (Z)", "%.2f Deg. (Heading)", orientation.getYaw(AngleUnit.DEGREES));
- telemetry.addData("Pitch (X)", "%.2f Deg.", orientation.getPitch(AngleUnit.DEGREES));
- telemetry.addData("Roll (Y)", "%.2f Deg.\n", orientation.getRoll(AngleUnit.DEGREES));
- telemetry.addData("Yaw (Z) velocity", "%.2f Deg/Sec", angularVelocity.zRotationRate);
- telemetry.addData("Pitch (X) velocity", "%.2f Deg/Sec", angularVelocity.xRotationRate);
- telemetry.addData("Roll (Y) velocity", "%.2f Deg/Sec", angularVelocity.yRotationRate);
- telemetry.update();
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUOrthogonal.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUOrthogonal.java
deleted file mode 100644
index af4c2028..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUOrthogonal.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/* Copyright (c) 2022 FIRST. 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.rev.RevHubOrientationOnRobot;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.IMU;
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-import org.firstinspires.ftc.robotcore.external.navigation.AngularVelocity;
-import org.firstinspires.ftc.robotcore.external.navigation.YawPitchRollAngles;
-
-/*
- * This OpMode shows how to use the new universal IMU interface. This
- * interface may be used with the BNO055 IMU or the BHI260 IMU. It assumes that an IMU is configured
- * on the robot with the name "imu".
- *
- * The sample will display the current Yaw, Pitch and Roll of the robot.
- * With the correct orientation parameters selected, pitch/roll/yaw should act as follows:
- * Pitch value should INCREASE as the robot is tipped UP at the front. (Rotation about X)
- * Roll value should INCREASE as the robot is tipped UP at the left side. (Rotation about Y)
- * Yaw value should INCREASE as the robot is rotated Counter Clockwise. (Rotation about Z)
- *
- * The yaw can be reset (to zero) by pressing the Y button on the gamepad (Triangle on a PS4 controller)
- *
- * This specific sample assumes that the Hub is mounted on one of the three orthogonal planes
- * (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
- * the alternative SensorIMUNonOrthogonal sample in this folder.
- *
- * This "Orthogonal" requirement means that:
- *
- * 1) The Logo printed on the top of the Hub can ONLY be pointing in one of six directions:
- * FORWARD, BACKWARD, UP, DOWN, LEFT and RIGHT.
- *
- * 2) The USB ports can only be pointing in one of the same six directions:
- * FORWARD, BACKWARD, UP, DOWN, LEFT and RIGHT.
- *
- * So, To fully define how your Hub is mounted to the robot, you must simply specify:
- * logoFacingDirection
- * usbFacingDirection
- *
- * 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.
- *
- * Finally, choose the two correct parameters to define how your Hub is mounted and edit this OpMode
- * to use those parameters.
- */
-@TeleOp(name = "Sensor: IMU Orthogonal", group = "Sensor")
-@Disabled // Comment this out to add to the OpMode list
-public class SensorIMUOrthogonal extends LinearOpMode
-{
- // The IMU sensor object
- IMU imu;
-
- //----------------------------------------------------------------------------------------------
- // Main logic
- //----------------------------------------------------------------------------------------------
-
- @Override public void runOpMode() throws InterruptedException {
-
- // Retrieve and initialize the IMU.
- // This sample expects the IMU to be in a REV Hub and named "imu".
- imu = hardwareMap.get(IMU.class, "imu");
-
- /* Define how the hub is mounted on the robot to get the correct Yaw, Pitch and Roll values.
- *
- * Two input parameters are required to fully specify the Orientation.
- * 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.
- * 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 Default Orientation (shown) is when a hub is mounted horizontally with the printed logo pointing UP and the USB port pointing FORWARD.
- *
- * To Do: EDIT these two lines to match YOUR mounting configuration.
- */
- RevHubOrientationOnRobot.LogoFacingDirection logoDirection = RevHubOrientationOnRobot.LogoFacingDirection.UP;
- RevHubOrientationOnRobot.UsbFacingDirection usbDirection = RevHubOrientationOnRobot.UsbFacingDirection.FORWARD;
-
- RevHubOrientationOnRobot orientationOnRobot = new RevHubOrientationOnRobot(logoDirection, usbDirection);
-
- // Now initialize the IMU with this mounting orientation
- // Note: if you choose two conflicting directions, this initialization will cause a code exception.
- imu.initialize(new IMU.Parameters(orientationOnRobot));
-
- // Loop and update the dashboard
- while (!isStopRequested()) {
-
- telemetry.addData("Hub orientation", "Logo=%s USB=%s\n ", logoDirection, usbDirection);
-
- // Check to see if heading reset is requested
- if (gamepad1.y) {
- telemetry.addData("Yaw", "Resetting\n");
- imu.resetYaw();
- } else {
- telemetry.addData("Yaw", "Press Y (triangle) on Gamepad to reset\n");
- }
-
- // Retrieve Rotational Angles and Velocities
- YawPitchRollAngles orientation = imu.getRobotYawPitchRollAngles();
- AngularVelocity angularVelocity = imu.getRobotAngularVelocity(AngleUnit.DEGREES);
-
- telemetry.addData("Yaw (Z)", "%.2f Deg. (Heading)", orientation.getYaw(AngleUnit.DEGREES));
- telemetry.addData("Pitch (X)", "%.2f Deg.", orientation.getPitch(AngleUnit.DEGREES));
- telemetry.addData("Roll (Y)", "%.2f Deg.\n", orientation.getRoll(AngleUnit.DEGREES));
- telemetry.addData("Yaw (Z) velocity", "%.2f Deg/Sec", angularVelocity.zRotationRate);
- telemetry.addData("Pitch (X) velocity", "%.2f Deg/Sec", angularVelocity.xRotationRate);
- telemetry.addData("Roll (Y) velocity", "%.2f Deg/Sec", angularVelocity.yRotationRate);
- telemetry.update();
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorKLNavxMicro.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorKLNavxMicro.java
deleted file mode 100644
index ccc945ff..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorKLNavxMicro.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.kauailabs.NavxMicroNavigationSensor;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.Gyroscope;
-import com.qualcomm.robotcore.hardware.IntegratingGyroscope;
-import com.qualcomm.robotcore.util.ElapsedTime;
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-import org.firstinspires.ftc.robotcore.external.navigation.AngularVelocity;
-import org.firstinspires.ftc.robotcore.external.navigation.AxesOrder;
-import org.firstinspires.ftc.robotcore.external.navigation.AxesReference;
-import org.firstinspires.ftc.robotcore.external.navigation.Orientation;
-
-/*
- * This OpMode shows how to use Kauai Labs navX Micro Robotics Navigation
- * Sensor. It assumes that the sensor is configured with a name of "navx".
- *
- * 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 = "Sensor: KL navX Micro", group = "Sensor")
-@Disabled
-public class SensorKLNavxMicro extends LinearOpMode {
-
- /** In this sample, for illustration purposes we use two interfaces on the one gyro object.
- * That's likely atypical: you'll probably use one or the other in any given situation,
- * depending on what you're trying to do. {@link IntegratingGyroscope} (and it's base interface,
- * {@link Gyroscope}) are common interfaces supported by possibly several different gyro
- * implementations. {@link NavxMicroNavigationSensor}, by contrast, provides functionality that
- * is unique to the navX Micro sensor.
- */
- IntegratingGyroscope gyro;
- NavxMicroNavigationSensor navxMicro;
-
- // A timer helps provide feedback while calibration is taking place
- ElapsedTime timer = new ElapsedTime();
-
- @Override public void runOpMode() throws InterruptedException {
- // Get a reference to a Modern Robotics GyroSensor object. We use several interfaces
- // on this object to illustrate which interfaces support which functionality.
- navxMicro = hardwareMap.get(NavxMicroNavigationSensor.class, "navx");
- gyro = (IntegratingGyroscope)navxMicro;
- // If you're only interested int the IntegratingGyroscope interface, the following will suffice.
- // gyro = hardwareMap.get(IntegratingGyroscope.class, "navx");
-
- // The gyro automatically starts calibrating. This takes a few seconds.
- telemetry.log().add("Gyro Calibrating. Do Not Move!");
-
- // Wait until the gyro calibration is complete
- timer.reset();
- while (navxMicro.isCalibrating()) {
- telemetry.addData("calibrating", "%s", Math.round(timer.seconds())%2==0 ? "|.." : "..|");
- telemetry.update();
- Thread.sleep(50);
- }
- telemetry.log().clear(); telemetry.log().add("Gyro Calibrated. Press Start.");
- telemetry.clear(); telemetry.update();
-
- // Wait for the start button to be pressed
- waitForStart();
- telemetry.log().clear();
-
- while (opModeIsActive()) {
-
- // Read dimensionalized data from the gyro. This gyro can report angular velocities
- // about all three axes. Additionally, it internally integrates the Z axis to
- // be able to report an absolute angular Z orientation.
- AngularVelocity rates = gyro.getAngularVelocity(AngleUnit.DEGREES);
- Orientation angles = gyro.getAngularOrientation(AxesReference.INTRINSIC, AxesOrder.ZYX, AngleUnit.DEGREES);
-
- telemetry.addLine()
- .addData("dx", formatRate(rates.xRotationRate))
- .addData("dy", formatRate(rates.yRotationRate))
- .addData("dz", "%s deg/s", formatRate(rates.zRotationRate));
-
- telemetry.addLine()
- .addData("heading", formatAngle(angles.angleUnit, angles.firstAngle))
- .addData("roll", formatAngle(angles.angleUnit, angles.secondAngle))
- .addData("pitch", "%s deg", formatAngle(angles.angleUnit, angles.thirdAngle));
- telemetry.update();
-
- idle(); // Always call idle() at the bottom of your while(opModeIsActive()) loop
- }
- }
-
- String formatRate(float rate) {
- return String.format("%.3f", rate);
- }
-
- String formatAngle(AngleUnit angleUnit, double angle) {
- return formatDegrees(AngleUnit.DEGREES.fromUnit(angleUnit, angle));
- }
-
- String formatDegrees(double degrees){
- return String.format("%.1f", AngleUnit.DEGREES.normalize(degrees));
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorLimelight3A.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorLimelight3A.java
deleted file mode 100644
index 6c1f702a..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorLimelight3A.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
-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 Limelight
- *
- * 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 barcodeResults = result.getBarcodeResults();
- for (LLResultTypes.BarcodeResult br : barcodeResults) {
- telemetry.addData("Barcode", "Data: %s", br.getData());
- }
-
- // Access classifier results
- List classifierResults = result.getClassifierResults();
- for (LLResultTypes.ClassifierResult cr : classifierResults) {
- telemetry.addData("Classifier", "Class: %s, Confidence: %.2f", cr.getClassName(), cr.getConfidence());
- }
-
- // Access detector results
- List detectorResults = result.getDetectorResults();
- for (LLResultTypes.DetectorResult dr : detectorResults) {
- telemetry.addData("Detector", "Class: %s, Area: %.2f", dr.getClassName(), dr.getTargetArea());
- }
-
- // Access fiducial results
- List 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 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();
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRColor.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRColor.java
deleted file mode 100644
index 32b37e09..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRColor.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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 android.app.Activity;
-import android.graphics.Color;
-import android.view.View;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.ColorSensor;
-
-/*
- *
- * This OpMode that shows how to use
- * a Modern Robotics Color Sensor.
- *
- * The OpMode assumes that the color sensor
- * is configured with a name of "sensor_color".
- *
- * You can use the X button on gamepad1 to toggle the LED on and off.
- *
- * 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 = "Sensor: MR Color", group = "Sensor")
-@Disabled
-public class SensorMRColor extends LinearOpMode {
-
- ColorSensor colorSensor; // Hardware Device Object
-
-
- @Override
- public void runOpMode() {
-
- // hsvValues is an array that will hold the hue, saturation, and value information.
- float hsvValues[] = {0F,0F,0F};
-
- // values is a reference to the hsvValues array.
- final float values[] = hsvValues;
-
- // get a reference to the RelativeLayout so we can change the background
- // color of the Robot Controller app to match the hue detected by the RGB sensor.
- int relativeLayoutId = hardwareMap.appContext.getResources().getIdentifier("RelativeLayout", "id", hardwareMap.appContext.getPackageName());
- final View relativeLayout = ((Activity) hardwareMap.appContext).findViewById(relativeLayoutId);
-
- // bPrevState and bCurrState represent the previous and current state of the button.
- boolean bPrevState = false;
- boolean bCurrState = false;
-
- // bLedOn represents the state of the LED.
- boolean bLedOn = true;
-
- // get a reference to our ColorSensor object.
- colorSensor = hardwareMap.get(ColorSensor.class, "sensor_color");
-
- // Set the LED in the beginning
- colorSensor.enableLed(bLedOn);
-
- // wait for the start button to be pressed.
- waitForStart();
-
- // while the OpMode is active, loop and read the RGB data.
- // Note we use opModeIsActive() as our loop condition because it is an interruptible method.
- while (opModeIsActive()) {
-
- // check the status of the x button on either gamepad.
- bCurrState = gamepad1.x;
-
- // check for button state transitions.
- if (bCurrState && (bCurrState != bPrevState)) {
-
- // button is transitioning to a pressed state. So Toggle LED
- bLedOn = !bLedOn;
- colorSensor.enableLed(bLedOn);
- }
-
- // update previous state variable.
- bPrevState = bCurrState;
-
- // convert the RGB values to HSV values.
- Color.RGBToHSV(colorSensor.red() * 8, colorSensor.green() * 8, colorSensor.blue() * 8, hsvValues);
-
- // send the info back to driver station using telemetry function.
- telemetry.addData("LED", bLedOn ? "On" : "Off");
- telemetry.addData("Clear", colorSensor.alpha());
- telemetry.addData("Red ", colorSensor.red());
- telemetry.addData("Green", colorSensor.green());
- telemetry.addData("Blue ", colorSensor.blue());
- telemetry.addData("Hue", hsvValues[0]);
-
- // change the background color to match the color detected by the RGB sensor.
- // pass a reference to the hue, saturation, and value array as an argument
- // to the HSVToColor method.
- relativeLayout.post(new Runnable() {
- public void run() {
- relativeLayout.setBackgroundColor(Color.HSVToColor(0xff, values));
- }
- });
-
- telemetry.update();
- }
-
- // Set the panel back to the default color
- relativeLayout.post(new Runnable() {
- public void run() {
- relativeLayout.setBackgroundColor(Color.WHITE);
- }
- });
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRGyro.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRGyro.java
deleted file mode 100644
index 91c0062e..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRGyro.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.modernrobotics.ModernRoboticsI2cGyro;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.IntegratingGyroscope;
-import com.qualcomm.robotcore.util.ElapsedTime;
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-import org.firstinspires.ftc.robotcore.external.navigation.AngularVelocity;
-import org.firstinspires.ftc.robotcore.external.navigation.AxesOrder;
-import org.firstinspires.ftc.robotcore.external.navigation.AxesReference;
-
-/*
- * This OpMode shows how to use the Modern Robotics Gyro.
- *
- * The OpMode assumes that the gyro sensor is attached to a Device Interface Module
- * I2C channel and is configured with a name of "gyro".
- *
- * 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 = "Sensor: MR Gyro", group = "Sensor")
-@Disabled
-public class SensorMRGyro extends LinearOpMode {
-
- /* In this sample, for illustration purposes we use two interfaces on the one gyro object.
- * That's likely atypical: you'll probably use one or the other in any given situation,
- * depending on what you're trying to do. {@link IntegratingGyroscope} (and it's base interface,
- * {@link Gyroscope}) are common interfaces supported by possibly several different gyro
- * implementations. {@link ModernRoboticsI2cGyro}, by contrast, provides functionality that
- * is unique to the Modern Robotics gyro sensor.
- */
- IntegratingGyroscope gyro;
- ModernRoboticsI2cGyro modernRoboticsI2cGyro;
-
- // A timer helps provide feedback while calibration is taking place
- ElapsedTime timer = new ElapsedTime();
-
- @Override
- public void runOpMode() {
-
- boolean lastResetState = false;
- boolean curResetState = false;
-
- // Get a reference to a Modern Robotics gyro object. We use several interfaces
- // on this object to illustrate which interfaces support which functionality.
- modernRoboticsI2cGyro = hardwareMap.get(ModernRoboticsI2cGyro.class, "gyro");
- gyro = (IntegratingGyroscope)modernRoboticsI2cGyro;
- // If you're only interested int the IntegratingGyroscope interface, the following will suffice.
- // gyro = hardwareMap.get(IntegratingGyroscope.class, "gyro");
- // A similar approach will work for the Gyroscope interface, if that's all you need.
-
- // Start calibrating the gyro. This takes a few seconds and is worth performing
- // during the initialization phase at the start of each OpMode.
- telemetry.log().add("Gyro Calibrating. Do Not Move!");
- modernRoboticsI2cGyro.calibrate();
-
- // Wait until the gyro calibration is complete
- timer.reset();
- while (!isStopRequested() && modernRoboticsI2cGyro.isCalibrating()) {
- telemetry.addData("calibrating", "%s", Math.round(timer.seconds())%2==0 ? "|.." : "..|");
- telemetry.update();
- sleep(50);
- }
-
- telemetry.log().clear(); telemetry.log().add("Gyro Calibrated. Press Start.");
- telemetry.clear(); telemetry.update();
-
- // Wait for the start button to be pressed
- waitForStart();
- telemetry.log().clear();
- telemetry.log().add("Press A & B to reset heading");
-
- // Loop until we're asked to stop
- while (opModeIsActive()) {
-
- // If the A and B buttons are pressed just now, reset Z heading.
- curResetState = (gamepad1.a && gamepad1.b);
- if (curResetState && !lastResetState) {
- modernRoboticsI2cGyro.resetZAxisIntegrator();
- }
- lastResetState = curResetState;
-
- // The raw() methods report the angular rate of change about each of the
- // three axes directly as reported by the underlying sensor IC.
- int rawX = modernRoboticsI2cGyro.rawX();
- int rawY = modernRoboticsI2cGyro.rawY();
- int rawZ = modernRoboticsI2cGyro.rawZ();
- int heading = modernRoboticsI2cGyro.getHeading();
- int integratedZ = modernRoboticsI2cGyro.getIntegratedZValue();
-
- // Read dimensionalized data from the gyro. This gyro can report angular velocities
- // about all three axes. Additionally, it internally integrates the Z axis to
- // be able to report an absolute angular Z orientation.
- AngularVelocity rates = gyro.getAngularVelocity(AngleUnit.DEGREES);
- float zAngle = gyro.getAngularOrientation(AxesReference.INTRINSIC, AxesOrder.ZYX, AngleUnit.DEGREES).firstAngle;
-
- // Read administrative information from the gyro
- int zAxisOffset = modernRoboticsI2cGyro.getZAxisOffset();
- int zAxisScalingCoefficient = modernRoboticsI2cGyro.getZAxisScalingCoefficient();
-
- telemetry.addLine()
- .addData("dx", formatRate(rates.xRotationRate))
- .addData("dy", formatRate(rates.yRotationRate))
- .addData("dz", "%s deg/s", formatRate(rates.zRotationRate));
- telemetry.addData("angle", "%s deg", formatFloat(zAngle));
- telemetry.addData("heading", "%3d deg", heading);
- telemetry.addData("integrated Z", "%3d", integratedZ);
- telemetry.addLine()
- .addData("rawX", formatRaw(rawX))
- .addData("rawY", formatRaw(rawY))
- .addData("rawZ", formatRaw(rawZ));
- telemetry.addLine().addData("z offset", zAxisOffset).addData("z coeff", zAxisScalingCoefficient);
- telemetry.update();
- }
- }
-
- String formatRaw(int rawValue) {
- return String.format("%d", rawValue);
- }
-
- String formatRate(float rate) {
- return String.format("%.3f", rate);
- }
-
- String formatFloat(float rate) {
- return String.format("%.3f", rate);
- }
-
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMROpticalDistance.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMROpticalDistance.java
deleted file mode 100644
index 6d2dfa39..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMROpticalDistance.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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 com.qualcomm.robotcore.hardware.OpticalDistanceSensor;
-
-/*
- * This OpMode shows how to use a Modern Robotics Optical Distance Sensor
- * It assumes that the ODS sensor is configured with a name of "sensor_ods".
- *
- * 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 = "Sensor: MR ODS", group = "Sensor")
-@Disabled
-public class SensorMROpticalDistance extends LinearOpMode {
-
- OpticalDistanceSensor odsSensor; // Hardware Device Object
-
- @Override
- public void runOpMode() {
-
- // get a reference to our Light Sensor object.
- odsSensor = hardwareMap.get(OpticalDistanceSensor.class, "sensor_ods");
-
- // wait for the start button to be pressed.
- waitForStart();
-
- // while the OpMode is active, loop and read the light levels.
- // Note we use opModeIsActive() as our loop condition because it is an interruptible method.
- while (opModeIsActive()) {
-
- // send the info back to driver station using telemetry function.
- telemetry.addData("Raw", odsSensor.getRawLightDetected());
- telemetry.addData("Normal", odsSensor.getLightDetected());
-
- telemetry.update();
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRRangeSensor.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRRangeSensor.java
deleted file mode 100644
index 2039ef97..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRRangeSensor.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.modernrobotics.ModernRoboticsI2cRangeSensor;
-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.DistanceUnit;
-
-/*
- * This OpMode illustrates how to use the Modern Robotics Range Sensor.
- *
- * The OpMode assumes that the range sensor is configured with a name of "sensor_range".
- *
- * 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
- *
- * @see MR Range Sensor
- */
-@TeleOp(name = "Sensor: MR range sensor", group = "Sensor")
-@Disabled // comment out or remove this line to enable this OpMode
-public class SensorMRRangeSensor extends LinearOpMode {
-
- ModernRoboticsI2cRangeSensor rangeSensor;
-
- @Override public void runOpMode() {
-
- // get a reference to our compass
- rangeSensor = hardwareMap.get(ModernRoboticsI2cRangeSensor.class, "sensor_range");
-
- // wait for the start button to be pressed
- waitForStart();
-
- while (opModeIsActive()) {
- telemetry.addData("raw ultrasonic", rangeSensor.rawUltrasonic());
- telemetry.addData("raw optical", rangeSensor.rawOptical());
- telemetry.addData("cm optical", "%.2f cm", rangeSensor.cmOptical());
- telemetry.addData("cm", "%.2f cm", rangeSensor.getDistance(DistanceUnit.CM));
- telemetry.update();
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorOctoQuad.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorOctoQuad.java
deleted file mode 100644
index 2300dd78..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorOctoQuad.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2024 DigitalChickenLabs
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.firstinspires.ftc.robotcontroller.external.samples;
-
-import com.qualcomm.hardware.digitalchickenlabs.OctoQuad;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import org.firstinspires.ftc.robotcore.external.Telemetry;
-
-/*
- * This OpMode illustrates how to use the DigitalChickenLabs OctoQuad Quadrature Encoder & Pulse Width Interface Module
- *
- * The OctoQuad has 8 input channels that can used to read either Relative Quadrature Encoders or Pulse-Width Absolute Encoder inputs.
- * Relative Quadrature encoders are found on most FTC motors, and some stand-alone position sensors like the REV Thru-Bore encoder.
- * Pulse-Width encoders are less common. The REV Thru-Bore encoder can provide its absolute position via a variable pulse width,
- * as can several sonar rangefinders such as the MaxBotix MB1000 series.
- *
- * This basic sample shows how an OctoQuad can be used to read the position three Odometry pods fitted
- * with REV Thru-Bore encoders. For a more advanced example showing additional OctoQuad capabilities, see the SensorOctoQuadAdv sample.
- *
- * This OpMode assumes that the OctoQuad is attached to an I2C interface named "octoquad" in the robot configuration.
- *
- * The code assumes the first three OctoQuad inputs are connected as follows
- * - Chan 0: for measuring forward motion on the left side of the robot.
- * - Chan 1: for measuring forward motion on the right side of the robot.
- * - Chan 2: for measuring Lateral (strafing) motion.
- *
- * The encoder values may be reset to zero by pressing the X (left most) button on Gamepad 1.
- *
- * This sample does not show how to interpret these readings, just how to obtain and display them.
- *
- * 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
- *
- * See the sensor's product page: https://www.tindie.com/products/35114/
- */
-@TeleOp(name = "OctoQuad Basic", group="OctoQuad")
-@Disabled
-public class SensorOctoQuad extends LinearOpMode {
-
- // 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_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)
-
- // Declare the OctoQuad object and members to store encoder positions and velocities
- private OctoQuad octoquad;
-
- private int posLeft;
- private int posRight;
- private int posPerp;
-
- /**
- * This function is executed when this OpMode is selected from the Driver Station.
- */
- @Override
- public void runOpMode() {
-
- // Connect to OctoQuad by referring to its name in the Robot Configuration.
- octoquad = hardwareMap.get(OctoQuad.class, "octoquad");
-
- // Read the Firmware Revision number from the OctoQuad and display it as telemetry.
- telemetry.addData("OctoQuad Firmware Version ", octoquad.getFirmwareVersion());
-
- // Reverse the count-direction of any encoder that is not what you require.
- // 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_RIGHT, OctoQuad.EncoderDirection.FORWARD);
- octoquad.setSingleEncoderDirection(ODO_PERP, OctoQuad.EncoderDirection.FORWARD);
-
- // Any changes that are made should be saved in FLASH just in case there is a sensor power glitch.
- octoquad.saveParametersToFlash();
-
- telemetry.addLine("\nPress START to read encoder values");
- telemetry.update();
-
- waitForStart();
-
- // Configure the telemetry for optimal display of data.
- telemetry.setDisplayFormat(Telemetry.DisplayFormat.MONOSPACE);
- telemetry.setMsTransmissionInterval(50);
-
- // Set all the encoder inputs to zero.
- octoquad.resetAllPositions();
-
- // Loop while displaying the odometry pod positions.
- while (opModeIsActive()) {
- telemetry.addData(">", "Press X to Reset Encoders\n");
-
- // Check for X button to reset encoders.
- if (gamepad1.x) {
- // Reset the position of all encoders to zero.
- octoquad.resetAllPositions();
- }
-
- // Read all the encoder data. Load into local members.
- readOdometryPods();
-
- // Display the values.
- telemetry.addData("Left ", "%8d counts", posLeft);
- telemetry.addData("Right", "%8d counts", posRight);
- telemetry.addData("Perp ", "%8d counts", posPerp);
- telemetry.update();
- }
- }
-
- private void readOdometryPods() {
- // For best performance, we should only perform ONE transaction with the OctoQuad each cycle.
- // Since this example only needs to read positions from a few channels, we could use either
- // readPositionRange(idxFirst, idxLast) to get a select number of sequential channels
- // or
- // readAllEncoderData() 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, we will read all of the encoder positions, and then pick out the ones we need.
- OctoQuad.EncoderDataBlock data = octoquad.readAllEncoderData();
- posLeft = data.positions[ODO_LEFT];
- posRight = data.positions[ODO_RIGHT];
- posPerp = data.positions[ODO_PERP];
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorOctoQuadAdv.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorOctoQuadAdv.java
deleted file mode 100644
index 2e807ce0..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorOctoQuadAdv.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright (c) 2024 DigitalChickenLabs
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.firstinspires.ftc.robotcontroller.external.samples;
-
-import com.qualcomm.hardware.digitalchickenlabs.OctoQuad;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.util.ElapsedTime;
-import com.qualcomm.robotcore.util.MovingStatistics;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-
-
-import org.firstinspires.ftc.robotcore.external.Telemetry;
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/*
- * This OpMode illustrates how to use advanced features of the DigitalChickenLabs OctoQuad Quadrature Encoder & Pulse Width Interface Module
- *
- * The OctoQuad has 8 input channels that can used to read either Quadrature Encoder signals (like with most FTC motors)
- * or Pulse-Width style Absolute Encoder inputs (eg: REV Through Bore encoder pulse width output).
- *
- * This OpMode illustrates several of the more advanced features of an OctoQuad, including Pulse Width measurement and velocity measurement.
- * For a more basic OpMode just showing how to read encoder inputs, see the SensorOctoQuad sample.
- *
- * This OpMode assumes that the OctoQuad is attached to an I2C interface named "octoquad" in the robot configuration.
- *
- * One system that requires a lot of encoder inputs is a Swerve Drive system.
- * Such a drive requires two encoders per drive module: one for position & velocity of the Drive motor/wheel, and one for position/angle of the Steering motor.
- * The Drive motor usually requires a quadrature encoder, and the Steering motor requires an Absolute encoder.
- * This quantity and combination of encoder inputs is a challenge, but a single OctoQuad could be used to read them all.
- *
- * This sample will configure an OctoQuad for a swerve drive, as follows
- * - Configure 4 Relative Quadrature Encoder inputs and 4 Absolute Pulse-Width Encoder inputs
- * - Configure a velocity sample interval of 25 mSec
- * - Configure a pulse width input range of 1-1024 uSec for a REV Through Bore Encoder's Absolute Pulse output.
- *
- * An OctoSwerveDrive class will be created to initialize the OctoQuad, and manage the 4 swerve modules.
- * An OctoSwerveModule class will be created to configure and read a single swerve module.
- *
- * Wiring:
- * The OctoQuad will be configured to accept Quadrature encoders on the first four channels and Absolute (pulse width) encoders on the last four channels.
- *
- * The standard 4-pin to 4-pin cable can be used to connect each Driver Motor encoder to the OctoQuad. (channels 0-3)
- *
- * A modified version of the REV 6-4 pin cable (shipped with the encoder) connects the steering encoder to the OctoQuad. (channels 4-7)
- * To connect the Absolute position signal from a REV Thru-Bore encoder to the OctoQuad, the Provided 6-pin to 4-pin cable will need to be modified.
- * At the 6-pin connector end, move the yellow wire from its initial pin-3 position to the ABS pin-5 position. This can be done easily
- * by using a small flathead screwdriver to lift the small white tab holding the metal wire crimp in place and gently pulling the wire out.
- * See the OctoSwerveDrive() constructor below for the correct wheel/channel assignment.
- *
- * 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
- *
- * 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.
- *
- * See the sensor's product page: https://www.tindie.com/products/35114/
- */
-@TeleOp(name="OctoQuad Advanced", group="OctoQuad")
-@Disabled
-public class SensorOctoQuadAdv extends LinearOpMode {
-
- @Override
- public void runOpMode() throws InterruptedException {
- // Connect to the OctoQuad by looking up its name in the hardwareMap.
- OctoQuad octoquad = hardwareMap.get(OctoQuad.class, "octoquad");
-
- // Create the interface for the Swerve Drive Encoders
- OctoSwerveDrive octoSwerveDrive = new OctoSwerveDrive(octoquad);
-
- // Display the OctoQuad firmware revision
- telemetry.addLine("OctoQuad Firmware v" + octoquad.getFirmwareVersion());
- telemetry.addLine("\nPress START to read encoder values");
- telemetry.update();
-
- waitForStart();
-
- // Configure the telemetry for optimal display of data.
- telemetry.setDisplayFormat(Telemetry.DisplayFormat.MONOSPACE);
- telemetry.setMsTransmissionInterval(50);
-
- // Run stats to determine cycle times.
- MovingStatistics avgTime = new MovingStatistics(100);
- ElapsedTime elapsedTime = new ElapsedTime();
-
- while (opModeIsActive()) {
- telemetry.addData(">", "Press X to Reset Encoders\n");
-
- if(gamepad1.x) {
- octoquad.resetAllPositions();
- }
-
- // read all the swerve drive encoders and update positions and velocities.
- octoSwerveDrive.updateModules();
- octoSwerveDrive.show(telemetry);
-
- // Update cycle time stats
- avgTime.add(elapsedTime.nanoseconds());
- elapsedTime.reset();
-
- telemetry.addData("Loop time", "%.1f mS", avgTime.getMean()/1000000);
- telemetry.update();
- }
- }
-}
-
-// ============================ Internal (Inner) Classes =============================
-
-/***
- * OctoSwerveDrive class manages 4 Swerve Modules
- * - Performs general OctoQuad initialization
- * - Creates 4 module classes, one for each swerve module
- * - Updates swerve drive status by reading all data from OctoQuad and Updating each module
- * - Displays all swerve drive data as telemetry
- */
-class OctoSwerveDrive {
-
- private final OctoQuad octoquad;
- private final List allModules = new ArrayList<>();
-
- // members to hold encoder data for each module.
- public final OctoSwerveModule LeftFront;
- public final OctoSwerveModule RightFront;
- public final OctoSwerveModule LeftBack;
- public final OctoSwerveModule RightBack;
-
- // Prepare an object to hold an entire OctoQuad encoder readable register bank (pos and vel)
- private final OctoQuad.EncoderDataBlock encoderDataBlock = new OctoQuad.EncoderDataBlock();
-
- public OctoSwerveDrive(OctoQuad octoquad) {
- this.octoquad = octoquad;
-
- // Clear out all prior settings and encoder data before setting up desired configuration
- octoquad.resetEverything();
-
- // Assume first 4 channels are relative encoders and the next 4 are absolute encoders
- octoquad.setChannelBankConfig(OctoQuad.ChannelBankConfig.BANK1_QUADRATURE_BANK2_PULSE_WIDTH);
-
- // Create the four OctoSwerveModules, and add them to a 'list' for easier reference.
-
- // Note: The wheel/channel order is set here. Ensure your encoder cables match.
- //
- // Note: The angleOffset must be set for each module so a forward facing wheel shows a steer angle of 0 degrees.
- // The process for determining the correct angleOffsets is as follows:
- // 1) Set all the angleValues (below) to zero then build and deploy the code.
- // 2) Physically rotate all the swerve drives so the wheels are facing forward in the desired 0 degree position
- // 3) Run the OpMode, view the telemetry and record the "Degrees" value for each module.
- // 4) Update the code by entering the recorded Degrees value for each module as the angleOffset (last) parameter in the lines below.
- //
- // Rebuild and deploy the new code. Verify that the telemetry now indicates 0 degrees when the wheels are facing forward.
- // Also verify that the correct module values change appropriately when you manually spin (drive) and rotate (steer) a wheel.
-
- allModules.add(LeftFront = new OctoSwerveModule(octoquad, "LF ",0,0));// Drive = 0, Steer = 4
- allModules.add(RightFront = new OctoSwerveModule(octoquad, "RF ",1,0));// Drive = 1, Steer = 5
- allModules.add(LeftBack = new OctoSwerveModule(octoquad, "LB ",2,0));// Drive = 2, Steer = 6
- allModules.add(RightBack = new OctoSwerveModule(octoquad, "RB ",3,0));// Drive = 3, Steer = 7
-
- // now make sure the settings persist through any power glitches.
- octoquad.saveParametersToFlash();
- }
-
- /**
- * Updates all 4 swerve modules
- */
- public void updateModules() {
- // Read full OctoQuad data block and then pass DataBlock to each swerve module to update themselves.
- octoquad.readAllEncoderData(encoderDataBlock);
- for (OctoSwerveModule module : allModules) {
- module.updateModule(encoderDataBlock);
- }
- }
-
- /**
- * Generate telemetry data for all modules.
- * @param telemetry OpMode Telemetry object
- */
- public void show(Telemetry telemetry) {
- // create general header block and then have each module add its own telemetry
- telemetry.addData("pos", " Count CPS Degree DPS");
- for (OctoSwerveModule module : allModules) {
- module.show(telemetry);
- }
- }
-}
-
-/***
- * The OctoSwerveModule class manages a single swerve module
- */
-class OctoSwerveModule {
-
- public double driveCounts;
- public double driveCountsPerSec;
- public double steerDegrees;
- public double steerDegreesPerSec;
-
- private final String name;
- private final int channel;
- private final double angleOffset;
- private final double steerDirMult;
-
- private static final int VELOCITY_SAMPLE_INTERVAL_MS = 25; // To provide 40 updates per second.
- private static final double DEGREES_PER_US = (360.0 / 1024.0); // based on REV Through Bore Encoder
- private static final double VELOCITY_SAMPLES_PER_S = (1000.0 / VELOCITY_SAMPLE_INTERVAL_MS);
-
- // The correct drive and turn directions must be set for the Swerve Module based on the specific hardware geometry.
- // Forward motion must generate an increasing drive count.
- // Counter Clockwise steer rotation must generate an increasing Steer Angle (degrees)
- private static final boolean INVERT_DRIVE_ENCODER = false; // Set true if forward motion decreases drive "Count"
- private static final boolean INVERT_STEER_ENCODER = false; // Set true if counter clockwise steer action decreases steer "Degree"
-
- /***
- * @param octoquad provide access to configure OctoQuad
- * @param name name used for telemetry display
- * @param quadChannel Quadrature encoder channel. Pulse Width channel is this + 4
- * @param angleOffset Angle to subtract from absolute encoder to calibrate zero position. (see comments above)
- */
- public OctoSwerveModule (OctoQuad octoquad, String name, int quadChannel, double angleOffset) {
- this.name = name;
- this.channel = quadChannel;
- this.angleOffset = angleOffset;
- this.steerDirMult = INVERT_STEER_ENCODER ? -1 : 1 ; // create a multiplier to flip the steer angle.
-
- // Set the drive encoder direction. Note the absolute encoder does not have built-in direction inversion.
- octoquad.setSingleEncoderDirection(channel, INVERT_DRIVE_ENCODER ? OctoQuad.EncoderDirection.REVERSE : OctoQuad.EncoderDirection.FORWARD);
-
- // Set the velocity sample interval on both encoders
- octoquad.setSingleVelocitySampleInterval(channel, VELOCITY_SAMPLE_INTERVAL_MS);
- octoquad.setSingleVelocitySampleInterval(channel + 4, VELOCITY_SAMPLE_INTERVAL_MS);
-
- // Setup Absolute encoder pulse range to match REV Through Bore encoder.
- octoquad.setSingleChannelPulseWidthParams (channel + 4, new OctoQuad.ChannelPulseWidthParams(1,1024));
- }
-
- /***
- * Calculate the Swerve module's position and velocity values
- * @param encoderDataBlock most recent full data block read from OctoQuad.
- */
- public void updateModule(OctoQuad.EncoderDataBlock encoderDataBlock) {
- driveCounts = encoderDataBlock.positions[channel]; // get Counts.
- driveCountsPerSec = encoderDataBlock.velocities[channel] * VELOCITY_SAMPLES_PER_S; // convert counts/interval to counts/sec
-
- // convert uS to degrees. Add in any possible direction flip.
- steerDegrees = AngleUnit.normalizeDegrees((encoderDataBlock.positions[channel+ 4] * DEGREES_PER_US * steerDirMult) - angleOffset);
- // convert uS/interval to deg per sec. Add in any possible direction flip.
- steerDegreesPerSec = encoderDataBlock.velocities[channel + 4] * DEGREES_PER_US * steerDirMult * VELOCITY_SAMPLES_PER_S;
- }
-
- /**
- * Display the Swerve module's state as telemetry
- * @param telemetry OpMode Telemetry object
- */
- public void show(Telemetry telemetry) {
- telemetry.addData(name, "%8.0f %7.0f %7.0f %6.0f", driveCounts, driveCountsPerSec, steerDegrees, steerDegreesPerSec);
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorREV2mDistance.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorREV2mDistance.java
deleted file mode 100644
index 13883c34..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorREV2mDistance.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-Copyright (c) 2018 FIRST
-
-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.rev.Rev2mDistanceSensor;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.DistanceSensor;
-import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit;
-
-/*
- * This OpMode illustrates how to use the REV Robotics 2M Distance Sensor.
- *
- * The OpMode assumes that the sensor is configured with a name of "sensor_distance".
- *
- * 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
- *
- * See the sensor's product page: https://www.revrobotics.com/rev-31-1505/
- */
-@TeleOp(name = "Sensor: REV2mDistance", group = "Sensor")
-@Disabled
-public class SensorREV2mDistance extends LinearOpMode {
-
- private DistanceSensor sensorDistance;
-
- @Override
- public void runOpMode() {
- // you can use this as a regular DistanceSensor.
- sensorDistance = hardwareMap.get(DistanceSensor.class, "sensor_distance");
-
- // you can also cast this to a Rev2mDistanceSensor if you want to use added
- // methods associated with the Rev2mDistanceSensor class.
- Rev2mDistanceSensor sensorTimeOfFlight = (Rev2mDistanceSensor) sensorDistance;
-
- telemetry.addData(">>", "Press start to continue");
- telemetry.update();
-
- waitForStart();
- while(opModeIsActive()) {
- // generic DistanceSensor methods.
- telemetry.addData("deviceName", sensorDistance.getDeviceName() );
- telemetry.addData("range", String.format("%.01f mm", sensorDistance.getDistance(DistanceUnit.MM)));
- telemetry.addData("range", String.format("%.01f cm", sensorDistance.getDistance(DistanceUnit.CM)));
- telemetry.addData("range", String.format("%.01f m", sensorDistance.getDistance(DistanceUnit.METER)));
- telemetry.addData("range", String.format("%.01f in", sensorDistance.getDistance(DistanceUnit.INCH)));
-
- // Rev2mDistanceSensor specific methods.
- telemetry.addData("ID", String.format("%x", sensorTimeOfFlight.getModelID()));
- telemetry.addData("did time out", Boolean.toString(sensorTimeOfFlight.didTimeoutOccur()));
-
- telemetry.update();
- }
- }
-
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorSparkFunOTOS.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorSparkFunOTOS.java
deleted file mode 100644
index 3a25230f..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorSparkFunOTOS.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- SPDX-License-Identifier: MIT
-
- Copyright (c) 2024 SparkFun Electronics
-*/
-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 com.qualcomm.hardware.sparkfun.SparkFunOTOS;
-
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit;
-
-/*
- * This OpMode illustrates how to use the SparkFun Qwiic Optical Tracking Odometry Sensor (OTOS)
- *
- * The OpMode assumes that the sensor is configured with a name of "sensor_otos".
- *
- * 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
- *
- * See the sensor's product page: https://www.sparkfun.com/products/24904
- */
-@TeleOp(name = "Sensor: SparkFun OTOS", group = "Sensor")
-@Disabled
-public class SensorSparkFunOTOS extends LinearOpMode {
- // Create an instance of the sensor
- SparkFunOTOS myOtos;
-
- @Override
- public void runOpMode() throws InterruptedException {
- // Get a reference to the sensor
- myOtos = hardwareMap.get(SparkFunOTOS.class, "sensor_otos");
-
- // All the configuration for the OTOS is done in this helper method, check it out!
- configureOtos();
-
- // Wait for the start button to be pressed
- waitForStart();
-
- // Loop until the OpMode ends
- while (opModeIsActive()) {
- // Get the latest position, which includes the x and y coordinates, plus the
- // heading angle
- SparkFunOTOS.Pose2D pos = myOtos.getPosition();
-
- // Reset the tracking if the user requests it
- if (gamepad1.y) {
- myOtos.resetTracking();
- }
-
- // Re-calibrate the IMU if the user requests it
- if (gamepad1.x) {
- myOtos.calibrateImu();
- }
-
- // Inform user of available controls
- telemetry.addLine("Press Y (triangle) on Gamepad to reset tracking");
- telemetry.addLine("Press X (square) on Gamepad to calibrate the IMU");
- telemetry.addLine();
-
- // Log the position to the telemetry
- telemetry.addData("X coordinate", pos.x);
- telemetry.addData("Y coordinate", pos.y);
- telemetry.addData("Heading angle", pos.h);
-
- // Update the telemetry on the driver station
- telemetry.update();
- }
- }
-
- private void configureOtos() {
- telemetry.addLine("Configuring OTOS...");
- telemetry.update();
-
- // Set the desired units for linear and angular measurements. Can be either
- // meters or inches for linear, and radians or degrees for angular. If not
- // set, the default is inches and degrees. Note that this setting is not
- // persisted in the sensor, so you need to set at the start of all your
- // OpModes if using the non-default value.
- // myOtos.setLinearUnit(DistanceUnit.METER);
- myOtos.setLinearUnit(DistanceUnit.INCH);
- // myOtos.setAngularUnit(AnguleUnit.RADIANS);
- myOtos.setAngularUnit(AngleUnit.DEGREES);
-
- // Assuming you've mounted your sensor to a robot and it's not centered,
- // you can specify the offset for the sensor relative to the center of the
- // robot. The units default to inches and degrees, but if you want to use
- // different units, specify them before setting the offset! Note that as of
- // firmware version 1.0, these values will be lost after a power cycle, so
- // you will need to set them each time you power up the sensor. For example, if
- // the sensor is mounted 5 inches to the left (negative X) and 10 inches
- // forward (positive Y) of the center of the robot, and mounted 90 degrees
- // clockwise (negative rotation) from the robot's orientation, the offset
- // would be {-5, 10, -90}. These can be any value, even the angle can be
- // tweaked slightly to compensate for imperfect mounting (eg. 1.3 degrees).
- SparkFunOTOS.Pose2D offset = new SparkFunOTOS.Pose2D(0, 0, 0);
- myOtos.setOffset(offset);
-
- // Here we can set the linear and angular scalars, which can compensate for
- // scaling issues with the sensor measurements. Note that as of firmware
- // version 1.0, these values will be lost after a power cycle, so you will
- // need to set them each time you power up the sensor. They can be any value
- // from 0.872 to 1.127 in increments of 0.001 (0.1%). It is recommended to
- // first set both scalars to 1.0, then calibrate the angular scalar, then
- // the linear scalar. To calibrate the angular scalar, spin the robot by
- // multiple rotations (eg. 10) to get a precise error, then set the scalar
- // to the inverse of the error. Remember that the angle wraps from -180 to
- // 180 degrees, so for example, if after 10 rotations counterclockwise
- // (positive rotation), the sensor reports -15 degrees, the required scalar
- // would be 3600/3585 = 1.004. To calibrate the linear scalar, move the
- // robot a known distance and measure the error; do this multiple times at
- // multiple speeds to get an average, then set the linear scalar to the
- // inverse of the error. For example, if you move the robot 100 inches and
- // the sensor reports 103 inches, set the linear scalar to 100/103 = 0.971
- myOtos.setLinearScalar(1.0);
- myOtos.setAngularScalar(1.0);
-
- // The IMU on the OTOS includes a gyroscope and accelerometer, which could
- // have an offset. Note that as of firmware version 1.0, the calibration
- // will be lost after a power cycle; the OTOS performs a quick calibration
- // when it powers up, but it is recommended to perform a more thorough
- // calibration at the start of all your OpModes. Note that the sensor must
- // be completely stationary and flat during calibration! When calling
- // calibrateImu(), you can specify the number of samples to take and whether
- // to wait until the calibration is complete. If no parameters are provided,
- // it will take 255 samples and wait until done; each sample takes about
- // 2.4ms, so about 612ms total
- myOtos.calibrateImu();
-
- // Reset the tracking algorithm - this resets the position to the origin,
- // but can also be used to recover from some rare tracking errors
- myOtos.resetTracking();
-
- // After resetting the tracking, the OTOS will report that the robot is at
- // the origin. If your robot does not start at the origin, or you have
- // another source of location information (eg. vision odometry), you can set
- // the OTOS location to match and it will continue to track from there.
- SparkFunOTOS.Pose2D currentPosition = new SparkFunOTOS.Pose2D(0, 0, 0);
- myOtos.setPosition(currentPosition);
-
- // Get the hardware and firmware version
- SparkFunOTOS.Version hwVersion = new SparkFunOTOS.Version();
- SparkFunOTOS.Version fwVersion = new SparkFunOTOS.Version();
- myOtos.getVersionInfo(hwVersion, fwVersion);
-
- telemetry.addLine("OTOS configured! Press start to get position data!");
- telemetry.addLine();
- telemetry.addLine(String.format("OTOS Hardware Version: v%d.%d", hwVersion.major, hwVersion.minor));
- telemetry.addLine(String.format("OTOS Firmware Version: v%d.%d", fwVersion.major, fwVersion.minor));
- telemetry.update();
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorTouch.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorTouch.java
deleted file mode 100644
index 3d794472..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorTouch.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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 com.qualcomm.robotcore.hardware.TouchSensor;
-
-/*
- * This OpMode demonstrates how to use a REV Robotics Touch Sensor, REV Robotics Magnetic Limit Switch, or other device
- * that implements the TouchSensor interface. Any touch sensor that connects its output to ground when pressed
- * (known as "active low") can be configured as a "REV Touch Sensor". This includes REV's Magnetic Limit Switch.
- *
- * The OpMode assumes that the touch sensor is configured with a name of "sensor_touch".
- *
- * A REV Robotics Touch Sensor must be configured on digital port number 1, 3, 5, or 7.
- * A Magnetic Limit Switch can be configured on any digital port.
- *
- * 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 = "Sensor: REV touch sensor", group = "Sensor")
-@Disabled
-public class SensorTouch extends LinearOpMode {
- TouchSensor touchSensor; // Touch sensor Object
-
- @Override
- public void runOpMode() {
-
- // get a reference to our touchSensor object.
- touchSensor = hardwareMap.get(TouchSensor.class, "sensor_touch");
-
- // wait for the start button to be pressed.
- waitForStart();
-
- // while the OpMode is active, loop and read whether the sensor is being pressed.
- // Note we use opModeIsActive() as our loop condition because it is an interruptible method.
- while (opModeIsActive()) {
-
- // send the info back to driver station using telemetry function.
- if (touchSensor.isPressed()) {
- telemetry.addData("Touch Sensor", "Is Pressed");
- } else {
- telemetry.addData("Touch Sensor", "Is Not Pressed");
- }
-
- telemetry.update();
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/UtilityCameraFrameCapture.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/UtilityCameraFrameCapture.java
deleted file mode 100644
index 69420cca..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/UtilityCameraFrameCapture.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2023 FIRST
- *
- * 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 android.util.Size;
-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.vision.VisionPortal;
-
-import java.util.Locale;
-
-/*
- * This OpMode helps calibrate a webcam or RC phone camera, useful for AprilTag pose estimation
- * with the FTC VisionPortal. It captures a camera frame (image) and stores it on the Robot Controller
- * (Control Hub or RC phone), with each press of the gamepad button X (or Square).
- * Full calibration instructions are here:
- *
- * https://ftc-docs.firstinspires.org/camera-calibration
- *
- * In Android Studio, copy this class into your "teamcode" folder with a new name.
- * Remove or comment out the @Disabled line to add this OpMode to the Driver Station OpMode list.
- *
- * In OnBot Java, use "Add File" to add this OpMode from the list of Samples.
- */
-
-@TeleOp(name = "Utility: Camera Frame Capture", group = "Utility")
-@Disabled
-public class UtilityCameraFrameCapture extends LinearOpMode
-{
- /*
- * EDIT THESE PARAMETERS AS NEEDED
- */
- final boolean USING_WEBCAM = false;
- final BuiltinCameraDirection INTERNAL_CAM_DIR = BuiltinCameraDirection.BACK;
- final int RESOLUTION_WIDTH = 640;
- final int RESOLUTION_HEIGHT = 480;
-
- // Internal state
- boolean lastX;
- int frameCount;
- long capReqTime;
-
- @Override
- public void runOpMode()
- {
- VisionPortal portal;
-
- if (USING_WEBCAM)
- {
- portal = new VisionPortal.Builder()
- .setCamera(hardwareMap.get(WebcamName.class, "Webcam 1"))
- .setCameraResolution(new Size(RESOLUTION_WIDTH, RESOLUTION_HEIGHT))
- .build();
- }
- else
- {
- portal = new VisionPortal.Builder()
- .setCamera(INTERNAL_CAM_DIR)
- .setCameraResolution(new Size(RESOLUTION_WIDTH, RESOLUTION_HEIGHT))
- .build();
- }
-
- while (!isStopRequested())
- {
- boolean x = gamepad1.x;
-
- if (x && !lastX)
- {
- portal.saveNextFrameRaw(String.format(Locale.US, "CameraFrameCapture-%06d", frameCount++));
- capReqTime = System.currentTimeMillis();
- }
-
- lastX = x;
-
- telemetry.addLine("######## Camera Capture Utility ########");
- telemetry.addLine(String.format(Locale.US, " > Resolution: %dx%d", RESOLUTION_WIDTH, RESOLUTION_HEIGHT));
- telemetry.addLine(" > Press X (or Square) to capture a frame");
- telemetry.addData(" > Camera Status", portal.getCameraState());
-
- if (capReqTime != 0)
- {
- telemetry.addLine("\nCaptured Frame!");
- }
-
- if (capReqTime != 0 && System.currentTimeMillis() - capReqTime > 1000)
- {
- capReqTime = 0;
- }
-
- telemetry.update();
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/UtilityOctoQuadConfigMenu.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/UtilityOctoQuadConfigMenu.java
deleted file mode 100644
index a962919f..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/UtilityOctoQuadConfigMenu.java
+++ /dev/null
@@ -1,812 +0,0 @@
-/*
- * Copyright (c) 2024 DigitalChickenLabs
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.firstinspires.ftc.robotcontroller.external.samples;
-
-import com.qualcomm.hardware.digitalchickenlabs.OctoQuad;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.Gamepad;
-
-import org.firstinspires.ftc.robotcore.external.Telemetry;
-
-import java.util.ArrayList;
-import java.util.Stack;
-
-/*
- * This OpMode illustrates how to use the DigitalChickenLabs OctoQuad Quadrature Encoder & Pulse Width Interface Module.
- *
- * The OctoQuad has 8 input channels that can used to read either Relative Quadrature Encoders or Pulse-Width Absolute Encoder inputs.
- * Relative Quadrature encoders are found on most FTC motors, and some stand-alone position sensors like the REV Thru-Bore encoder.
- * Pulse-Width encoders are less common. The REV Thru-Bore encoder can provide its absolute position via a variable pulse width,
- * as can several sonar rangefinders such as the MaxBotix MB1000 series.
- *
- * This OpMode assumes that the OctoQuad is attached to an I2C interface named "octoquad" in the robot configuration.
- *
- * Remove or comment out the @Disabled line to add this OpMode to the Driver Station OpMode list
- *
- * Select, Init and run the "OctoQuad Configuration Tool" OpMode
- * Read the blue User-Interface tips at the top of the telemetry screen.
- * Use the UI buttons to navigate the menu and make any desired changes to the OctoQuad configuration.
- * Use the Program Settings To FLASH option to make any changes permanent.
- *
- * See the sensor's product page: https://www.tindie.com/products/digitalchickenlabs/octoquad-8ch-quadrature-pulse-width-decoder/
- */
-@TeleOp(name = "OctoQuad Configuration Tool", group="OctoQuad")
-@Disabled
-public class UtilityOctoQuadConfigMenu extends LinearOpMode
-{
- TelemetryMenu.MenuElement rootMenu = new TelemetryMenu.MenuElement("OctoQuad Config Menu", true);
- TelemetryMenu.MenuElement menuHwInfo = new TelemetryMenu.MenuElement("Hardware Information", false);
- TelemetryMenu.EnumOption optionI2cResetMode;
- TelemetryMenu.EnumOption optionChannelBankConfig;
-
- TelemetryMenu.MenuElement menuEncoderDirections = new TelemetryMenu.MenuElement("Set Encoder Directions", false);
- TelemetryMenu.BooleanOption[] optionsEncoderDirections = new TelemetryMenu.BooleanOption[OctoQuad.NUM_ENCODERS];
-
- TelemetryMenu.MenuElement menuVelocityIntervals = new TelemetryMenu.MenuElement("Velocity Measurement Intervals", false);
- TelemetryMenu.IntegerOption[] optionsVelocityIntervals = new TelemetryMenu.IntegerOption[OctoQuad.NUM_ENCODERS];
-
- TelemetryMenu.MenuElement menuAbsParams = new TelemetryMenu.MenuElement("Abs. Encoder Pulse Width Params", false);
- TelemetryMenu.IntegerOption[] optionsAbsParamsMax = new TelemetryMenu.IntegerOption[OctoQuad.NUM_ENCODERS];
- TelemetryMenu.IntegerOption[] optionsAbsParamsMin = new TelemetryMenu.IntegerOption[OctoQuad.NUM_ENCODERS];
-
- TelemetryMenu.OptionElement optionProgramToFlash;
- TelemetryMenu.OptionElement optionSendToRAM;
-
- TelemetryMenu.StaticClickableOption optionExit;
-
- OctoQuad octoquad;
-
- boolean error = false;
-
- @Override
- public void runOpMode()
- {
- octoquad = hardwareMap.getAll(OctoQuad.class).get(0);
-
- if(octoquad.getChipId() != OctoQuad.OCTOQUAD_CHIP_ID)
- {
- telemetry.addLine("Error: cannot communicate with OctoQuad. Check your wiring and configuration and try again");
- telemetry.update();
-
- error = true;
- }
- else
- {
- if(octoquad.getFirmwareVersion().maj != OctoQuad.SUPPORTED_FW_VERSION_MAJ)
- {
- telemetry.addLine("Error: The OctoQuad is running a different major firmware version than this driver was built for. Cannot run configuration tool");
- telemetry.update();
-
- error = true;
- }
- }
-
- if(error)
- {
- waitForStart();
- return;
- }
-
- telemetry.addLine("Retrieving current configuration from OctoQuad");
- telemetry.update();
-
- optionExit = new TelemetryMenu.StaticClickableOption("Exit configuration menu")
- {
- @Override
- void onClick() // called on OpMode thread
- {
- requestOpModeStop();
- }
- };
-
- optionI2cResetMode = new TelemetryMenu.EnumOption("I2C Reset Mode", OctoQuad.I2cRecoveryMode.values(), octoquad.getI2cRecoveryMode());
- optionChannelBankConfig = new TelemetryMenu.EnumOption("Channel Bank Modes", OctoQuad.ChannelBankConfig.values(), octoquad.getChannelBankConfig());
-
- menuHwInfo.addChild(new TelemetryMenu.StaticItem("Board Firmware: v" + octoquad.getFirmwareVersion()));
- //menuHwInfo.addChild(new TelemetryMenu.StaticItem("Board unique ID: FIXME"));
-
- for(int i = 0; i < OctoQuad.NUM_ENCODERS; i++)
- {
- optionsEncoderDirections[i] = new TelemetryMenu.BooleanOption(
- String.format("Encoder %d direction", i),
- octoquad.getSingleEncoderDirection(i) == OctoQuad.EncoderDirection.REVERSE,
- "-",
- "+");
- }
- menuEncoderDirections.addChildren(optionsEncoderDirections);
-
- for(int i = 0; i < OctoQuad.NUM_ENCODERS; i++)
- {
- optionsVelocityIntervals[i] = new TelemetryMenu.IntegerOption(
- String.format("Chan %d velocity intvl", i),
- OctoQuad.MIN_VELOCITY_MEASUREMENT_INTERVAL_MS,
- OctoQuad.MAX_VELOCITY_MEASUREMENT_INTERVAL_MS,
- octoquad.getSingleVelocitySampleInterval(i));
- }
- menuVelocityIntervals.addChildren(optionsVelocityIntervals);
-
- for(int i = 0; i < OctoQuad.NUM_ENCODERS; i++)
- {
- OctoQuad.ChannelPulseWidthParams params = octoquad.getSingleChannelPulseWidthParams(i);
-
- optionsAbsParamsMax[i] = new TelemetryMenu.IntegerOption(
- String.format("Chan %d max pulse length", i),
- OctoQuad.MIN_PULSE_WIDTH_US,
- OctoQuad.MAX_PULSE_WIDTH_US,
- params.max_length_us);
-
- optionsAbsParamsMin[i] = new TelemetryMenu.IntegerOption(
- String.format("Chan %d min pulse length", i),
- OctoQuad.MIN_PULSE_WIDTH_US,
- OctoQuad.MAX_PULSE_WIDTH_US,
- params.min_length_us);
- }
- menuAbsParams.addChildren(optionsAbsParamsMin);
- menuAbsParams.addChildren(optionsAbsParamsMax);
-
- optionProgramToFlash = new TelemetryMenu.OptionElement()
- {
- String name = "Program Settings to FLASH";
- long lastClickTime = 0;
-
- @Override
- protected String getDisplayText()
- {
- if(lastClickTime == 0)
- {
- return name;
- }
- else
- {
- if(System.currentTimeMillis() - lastClickTime < 1000)
- {
- return name + " **OK**";
- }
- else
- {
- lastClickTime = 0;
- return name;
- }
- }
- }
-
- @Override
- void onClick()
- {
- sendSettingsToRam();
- octoquad.saveParametersToFlash();
- lastClickTime = System.currentTimeMillis();
- }
- };
-
- optionSendToRAM = new TelemetryMenu.OptionElement()
- {
- String name = "Send Settings to RAM";
- long lastClickTime = 0;
-
- @Override
- protected String getDisplayText()
- {
- if(lastClickTime == 0)
- {
- return name;
- }
- else
- {
- if(System.currentTimeMillis() - lastClickTime < 1000)
- {
- return name + " **OK**";
- }
- else
- {
- lastClickTime = 0;
- return name;
- }
- }
- }
-
- @Override
- void onClick()
- {
- sendSettingsToRam();
- lastClickTime = System.currentTimeMillis();
- }
- };
-
- rootMenu.addChild(menuHwInfo);
- rootMenu.addChild(optionI2cResetMode);
- rootMenu.addChild(optionChannelBankConfig);
- rootMenu.addChild(menuEncoderDirections);
- rootMenu.addChild(menuVelocityIntervals);
- rootMenu.addChild(menuAbsParams);
- rootMenu.addChild(optionProgramToFlash);
- rootMenu.addChild(optionSendToRAM);
- rootMenu.addChild(optionExit);
-
- TelemetryMenu menu = new TelemetryMenu(telemetry, rootMenu);
-
- while (!isStopRequested())
- {
- menu.loop(gamepad1);
- telemetry.update();
- sleep(20);
- }
- }
-
- void sendSettingsToRam()
- {
- for(int i = 0; i < OctoQuad.NUM_ENCODERS; i++)
- {
- octoquad.setSingleEncoderDirection(i, optionsEncoderDirections[i].getValue() ? OctoQuad.EncoderDirection.REVERSE : OctoQuad.EncoderDirection.FORWARD);
- octoquad.setSingleVelocitySampleInterval(i, optionsVelocityIntervals[i].getValue());
-
- OctoQuad.ChannelPulseWidthParams params = new OctoQuad.ChannelPulseWidthParams();
- params.max_length_us = optionsAbsParamsMax[i].getValue();
- params.min_length_us = optionsAbsParamsMin[i].getValue();
-
- octoquad.setSingleChannelPulseWidthParams(i, params);
- }
-
- octoquad.setI2cRecoveryMode((OctoQuad.I2cRecoveryMode) optionI2cResetMode.getValue());
- octoquad.setChannelBankConfig((OctoQuad.ChannelBankConfig) optionChannelBankConfig.getValue());
- }
-
- /*
- * Copyright (c) 2023 OpenFTC Team
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
- public static class TelemetryMenu
- {
- private final MenuElement root;
- private MenuElement currentLevel;
-
- private boolean dpadUpPrev;
- private boolean dpadDnPrev;
- private boolean dpadRightPrev;
- private boolean dpadLeftPrev;
- private boolean xPrev;
- private boolean lbPrev;
-
- private int selectedIdx = 0;
- private Stack selectedIdxStack = new Stack<>();
-
- private final Telemetry telemetry;
-
- /**
- * TelemetryMenu constructor
- * @param telemetry pass in 'telemetry' from your OpMode
- * @param root the root menu element
- */
- public TelemetryMenu(Telemetry telemetry, MenuElement root)
- {
- this.root = root;
- this.currentLevel = root;
- this.telemetry = telemetry;
-
- telemetry.setDisplayFormat(Telemetry.DisplayFormat.HTML);
- telemetry.setMsTransmissionInterval(50);
- }
-
- /**
- * Call this from inside your loop to put the current menu state into
- * telemetry, and process gamepad inputs for navigating the menu
- * @param gamepad the gamepad you want to use to navigate the menu
- */
- public void loop(Gamepad gamepad)
- {
- // Capture current state of the gamepad buttons we care about;
- // We can only look once or we risk a race condition
- boolean dpadUp = gamepad.dpad_up;
- boolean dpadDn = gamepad.dpad_down;
- boolean dpadRight = gamepad.dpad_right;
- boolean dpadLeft = gamepad.dpad_left;
- boolean x = gamepad.x;
- boolean lb = gamepad.left_bumper;
-
- // Figure out who our children our at this level
- // and figure out which item is currently highlighted
- // with the selection pointer
- ArrayList children = currentLevel.children();
- Element currentSelection = children.get(selectedIdx);
-
- // Left and right are inputs to the selected item (if it's an Option)
- if (currentSelection instanceof OptionElement)
- {
- if (dpadRight && !dpadRightPrev) // rising edge
- {
- ((OptionElement) currentSelection).onRightInput();
- }
- else if (dpadLeft && !dpadLeftPrev) // rising edge
- {
- ((OptionElement) currentSelection).onLeftInput();
- }
- }
-
- // Up and down navigate the current selection pointer
- if (dpadUp && !dpadUpPrev) // rising edge
- {
- selectedIdx--; // Move selection pointer up
- }
- else if (dpadDn && !dpadDnPrev) // rising edge
- {
- selectedIdx++; // Move selection pointer down
- }
-
- // Make selected index sane (don't let it go out of bounds) :eyes:
- if (selectedIdx >= children.size())
- {
- selectedIdx = children.size()-1;
- }
- else if (selectedIdx < 0)
- {
- selectedIdx = 0;
- }
-
- // Select: either enter submenu or input to option
- else if (x && !xPrev) // rising edge
- {
- // Select up element
- if (currentSelection instanceof SpecialUpElement)
- {
- // We can only go up if we're not at the root level
- if (currentLevel != root)
- {
- // Restore selection pointer to where it was before
- selectedIdx = selectedIdxStack.pop();
-
- // Change to the parent level
- currentLevel = currentLevel.parent();
- }
- }
- // Input to option
- else if (currentSelection instanceof OptionElement)
- {
- ((OptionElement) currentSelection).onClick();
- }
- // Enter submenu
- else if (currentSelection instanceof MenuElement)
- {
- // Save our current selection pointer so we can restore it
- // later if the user navigates back up a level
- selectedIdxStack.push(selectedIdx);
-
- // We have no idea what's in the submenu :monkey: so best to
- // just set the selection pointer to the first element
- selectedIdx = 0;
-
- // Now the current level becomes the submenu that the selection
- // pointer was on
- currentLevel = (MenuElement) currentSelection;
- }
- }
-
- // Go up a level
- else if (lb && !lbPrev)
- {
- // We can only go up if we're not at the root level
- if (currentLevel != root)
- {
- // Restore selection pointer to where it was before
- selectedIdx = selectedIdxStack.pop();
-
- // Change to the parent level
- currentLevel = currentLevel.parent();
- }
- }
-
- // Save the current button states so that we can look for
- // the rising edge the next time around the loop :)
- dpadUpPrev = dpadUp;
- dpadDnPrev = dpadDn;
- dpadRightPrev = dpadRight;
- dpadLeftPrev = dpadLeft;
- xPrev = x;
- lbPrev = lb;
-
- // Start building the text display.
- // First, we add the static directions for gamepad operation
- StringBuilder builder = new StringBuilder();
- builder.append("");
- builder.append("Navigate items.....dpad up/down\n")
- .append("Select.............X or Square\n")
- .append("Edit option........dpad left/right\n")
- .append("Up one level.......left bumper\n");
- builder.append("");
- builder.append("\n");
-
- // Now actually add the menu options. We start by adding the name of the current menu level.
- builder.append("");
- builder.append("Current Menu: ").append(currentLevel.name).append("\n");
-
- // Now we loop through all the child elements of this level and add them
- for (int i = 0; i < children.size(); i++)
- {
- // If the selection pointer is at this index, put a green dot in the box :)
- if (selectedIdx == i)
- {
- builder.append("[•] ");
- }
- // Otherwise, just put an empty box
- else
- {
- builder.append("[ ] ");
- }
-
- // Figure out who the selection pointer is pointing at :eyes:
- Element e = children.get(i);
-
- // If it's pointing at a submenu, indicate that it's a submenu to the user
- // by prefixing "> " to the name.
- if (e instanceof MenuElement)
- {
- builder.append("> ");
- }
-
- // Finally, add the element's name
- builder.append(e.getDisplayText());
-
- // We musn't forget the newline
- builder.append("\n");
- }
-
- // Don't forget to close the font tag either
- builder.append("");
-
- // Build the string!!!! :nerd:
- String menu = builder.toString();
-
- // Add it to telemetry
- telemetry.addLine(menu);
- }
-
- public static class MenuElement extends Element
- {
- private String name;
- private ArrayList children = new ArrayList<>();
-
- /**
- * Create a new MenuElement; may either be the root menu, or a submenu (set isRoot accordingly)
- * @param name the name for this menu
- * @param isRoot whether this is a root menu, or a submenu
- */
- public MenuElement(String name, boolean isRoot)
- {
- this.name = name;
-
- // If it's not the root menu, we add the up one level option as the first element
- if (!isRoot)
- {
- children.add(new SpecialUpElement());
- }
- }
-
- /**
- * Add a child element to this menu (may either be an Option or another menu)
- * @param child the child element to add
- */
- public void addChild(Element child)
- {
- child.setParent(this);
- children.add(child);
- }
-
- /**
- * Add multiple child elements to this menu (may either be option, or another menu)
- * @param children the children to add
- */
- public void addChildren(Element[] children)
- {
- for (Element e : children)
- {
- e.setParent(this);
- this.children.add(e);
- }
- }
-
- @Override
- protected String getDisplayText()
- {
- return name;
- }
-
- private ArrayList children()
- {
- return children;
- }
- }
-
- public static abstract class OptionElement extends Element
- {
- /**
- * Override this to get notified when the element is clicked
- */
- void onClick() {}
-
- /**
- * Override this to get notified when the element gets a "left edit" input
- */
- protected void onLeftInput() {}
-
- /**
- * Override this to get notified when the element gets a "right edit" input
- */
- protected void onRightInput() {}
- }
-
- public static class EnumOption extends OptionElement
- {
- protected int idx = 0;
- protected Enum[] e;
- protected String name;
-
- public EnumOption(String name, Enum[] e)
- {
- this.e = e;
- this.name = name;
- }
-
- public EnumOption(String name, Enum[] e, Enum def)
- {
- this(name, e);
- idx = def.ordinal();
- }
-
- @Override
- public void onLeftInput()
- {
- idx++;
-
- if(idx > e.length-1)
- {
- idx = 0;
- }
- }
-
- @Override
- public void onRightInput()
- {
- idx--;
-
- if(idx < 0)
- {
- idx = e.length-1;
- }
- }
-
- @Override
- public void onClick()
- {
- //onRightInput();
- }
-
- @Override
- protected String getDisplayText()
- {
- return String.format("%s: %s", name, e[idx].name());
- }
-
- public Enum getValue()
- {
- return e[idx];
- }
- }
-
- public static class IntegerOption extends OptionElement
- {
- protected int i;
- protected int min;
- protected int max;
- protected String name;
-
- public IntegerOption(String name, int min, int max, int def)
- {
- this.name = name;
- this.min = min;
- this.max = max;
- this.i = def;
- }
-
- @Override
- public void onLeftInput()
- {
- i--;
-
- if(i < min)
- {
- i = max;
- }
- }
-
- @Override
- public void onRightInput()
- {
- i++;
-
- if(i > max)
- {
- i = min;
- }
- }
-
- @Override
- public void onClick()
- {
- //onRightInput();
- }
-
- @Override
- protected String getDisplayText()
- {
- return String.format("%s: %d", name, i);
- }
-
- public int getValue()
- {
- return i;
- }
- }
-
- static class BooleanOption extends OptionElement
- {
- private String name;
- private boolean val = true;
-
- private String customTrue;
- private String customFalse;
-
- BooleanOption(String name, boolean def)
- {
- this.name = name;
- this.val = def;
- }
-
- BooleanOption(String name, boolean def, String customTrue, String customFalse)
- {
- this(name, def);
- this.customTrue = customTrue;
- this.customFalse = customFalse;
- }
-
- @Override
- public void onLeftInput()
- {
- val = !val;
- }
-
- @Override
- public void onRightInput()
- {
- val = !val;
- }
-
- @Override
- public void onClick()
- {
- val = !val;
- }
-
- @Override
- protected String getDisplayText()
- {
- String valStr;
-
- if(customTrue != null && customFalse != null)
- {
- valStr = val ? customTrue : customFalse;
- }
- else
- {
- valStr = val ? "true" : "false";
- }
-
- return String.format("%s: %s", name, valStr);
- }
-
- public boolean getValue()
- {
- return val;
- }
- }
-
- /**
- *
- */
- public static class StaticItem extends OptionElement
- {
- private String name;
-
- public StaticItem(String name)
- {
- this.name = name;
- }
-
- @Override
- protected String getDisplayText()
- {
- return name;
- }
- }
-
- public static abstract class StaticClickableOption extends OptionElement
- {
- private String name;
-
- public StaticClickableOption(String name)
- {
- this.name = name;
- }
-
- abstract void onClick();
-
- @Override
- protected String getDisplayText()
- {
- return name;
- }
- }
-
- private static abstract class Element
- {
- private MenuElement parent;
-
- protected void setParent(MenuElement parent)
- {
- this.parent = parent;
- }
-
- protected MenuElement parent()
- {
- return parent;
- }
-
- protected abstract String getDisplayText();
- }
-
- private static class SpecialUpElement extends Element
- {
- @Override
- protected String getDisplayText()
- {
- return ".. ↰ Up One Level";
- }
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/readme.md b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/readme.md
deleted file mode 100644
index 326978de..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/readme.md
+++ /dev/null
@@ -1,45 +0,0 @@
-
-## Caution
-No Team-specific code should be placed or modified in this ``.../samples`` folder.
-
-Samples should be Copied from here, and then Pasted into the team's
-[/TeamCode/src/main/java/org/firstinspires/ftc/teamcode](../../../../../../../../../../TeamCode/src/main/java/org/firstinspires/ftc/teamcode)
- folder, using the Android Studio cut and paste commands. This automatically changes all file and
-class names to be consistent. From there, the sample can be modified to suit the team's needs.
-
-For more detailed instructions see the /teamcode readme.
-
-### Naming of Samples
-
-To gain a better understanding of how the samples are organized, and how to interpret the
-naming system, it will help to understand the conventions that were used during their creation.
-
-These conventions are described (in detail) in the sample_conventions.md file in this folder.
-
-To summarize: A range of different samples classes will reside in the java/external/samples.
-The class names will follow a naming convention which indicates the purpose of each class.
-The prefix of the name will be one of the following:
-
-Basic: This is a minimally functional OpMode used to illustrate the skeleton/structure
- of a particular style of OpMode. These are bare bones examples.
-
-Sensor: This is a Sample OpMode that shows how to use a specific sensor.
- It is not intended to drive a functioning robot, it is simply showing the minimal code
- required to read and display the sensor values.
-
-Robot: This is a Sample OpMode that assumes a simple two-motor (differential) drive base.
- It may be used to provide a common baseline driving OpMode, or
- to demonstrate how a particular sensor or concept can be used to navigate.
-
-Concept: This is a sample OpMode that illustrates performing a specific function or concept.
- These may be complex, but their operation should be explained clearly in the comments,
- or the comments should reference an external doc, guide or tutorial.
- Each OpMode should try to only demonstrate a single concept so they are easy to
- locate based on their name. These OpModes may not produce a drivable robot.
-
-After the prefix, other conventions will apply:
-
-* Sensor class names are constructed as: Sensor - Company - Type
-* Robot class names are constructed as: Robot - Mode - Action - OpModetype
-* Concept class names are constructed as: Concept - Topic - OpModetype
-
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/sample_conventions.md b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/sample_conventions.md
deleted file mode 100644
index e85e6254..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/sample_conventions.md
+++ /dev/null
@@ -1,113 +0,0 @@
-## Sample Class/Opmode conventions
-#### V 1.1.0 8/9/2017
-
-This document defines the FTC Sample OpMode and Class conventions.
-
-### OpMode Name
-
-To gain a better understanding of how the samples are organized, and how to interpret the
-naming system, it will help to understand the conventions that were used during their creation.
-
-To summarize: A range of different samples classes will reside in the java/external/samples.
-The class names will follow a naming convention which indicates the purpose of each class.
-The prefix of the name will be one of the following:
-
-Basic: This is a minimally functional OpMode used to illustrate the skeleton/structure
- of a particular style of OpMode. These are bare bones examples.
-
-Sensor: This is a Sample OpMode that shows how to use a specific sensor.
- It is not intended to drive a functioning robot, it is simply showing the minimal code
- required to read and display the sensor values.
-
-Robot: This is a Sample OpMode that assumes a simple two-motor (differential) drive base.
- It may be used to provide a common baseline driving OpMode, or
- to demonstrate how a particular sensor or concept can be used to navigate.
-
-Concept: This is a sample OpMode that illustrates performing a specific function or concept.
- These may be complex, but their operation should be explained clearly in the comments,
- or the comments should reference an external doc, guide or tutorial.
- Each OpMode should try to only demonstrate a single concept so they are easy to
- locate based on their name. These OpModes may not produce a drivable robot.
-
-Utility: This sample type is provided as a useful tool, or aide, to perform some specific development task.
- It is not expected to be something you would include in your own robot code.
- To use the tool, comment out the @Disabled annotation and build the App.
- Read the comments found in the sample for an explanation of its intended use.
-
-After the prefix, other conventions will apply:
-
-* Sensor class names should constructed as: Sensor - Company - Type
-* Robot class names should be constructed as: Robot - Mode - Action - OpModetype
-* Concept class names should be constructed as: Concept - Topic - OpModetype
-
-### Sample OpMode Content/Style
-
-Code is formatted as per the Google Style Guide:
-
-https://google.github.io/styleguide/javaguide.html
-
-With “Sensor” and “Hardware” samples, the code should demonstrate the essential function,
-and not be embellished with too much additional “clever” code. If a sensor has special
-addressing needs, or has a variety of modes or outputs, these should be demonstrated as
-simply as possible.
-
-Special programming methods, or robot control techniques should be reserved for “Concept” Samples,
-and where possible, Samples should strive to only demonstrate a single concept,
-eg: State machine coding, or a User Menu system, and not combine them into a single “all inclusive”
-sample. This will prevent an “all inclusive” Sample being deleted just because one part of it
-becomes obsolete.
-
-### Device Configuration Names
-
-The following device names are used in the external samples
-
-** Motors:
-left_drive
-right_drive
-left_arm
-
-** Servos:
-left_hand
-right_hand
-arm
-claw
-
-** Sensors:
-sensor_color
-sensor_ir
-sensor_light
-sensor_ods
-sensor_range
-sensor_touch
-sensor_color_distance
-sensor_digital
-digin
-digout
-
-** Localization:
-compass
-gyro
-imu
-navx
-
-### Device Object Names
-
-Device Object names should use the same words as the device’s configuration name, but they
-should be re-structured to be a suitable Java variable name. This should keep the same word order,
-but adopt the style of beginning with a lower case letter, and then each subsequent word
-starting with an upper case letter.
-
-Eg: from the examples above: tool, leftMotor, rightClawServo, rearLightSensor.
-
-Note: Sometimes it’s helpful to put the device type first, followed by the variant.
-eg: motorLeft and motorRight, but this should only be done if the same word order
-is used on the device configuration name.
-
-### OpMode code Comments
-
-Sample comments should read like normal code comments, that is, as an explanation of what the
-sample code is doing. They should NOT be directives to the user,
-like: “insert your joystick code here” as these comments typically aren’t
-detailed enough to be useful. They also often get left in the code and become garbage.
-
-Instead, an example of the joystick code should be shown with a comment describing what it is doing.
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/FtcOpModeRegister.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/FtcOpModeRegister.java
deleted file mode 100644
index ceab67db..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/FtcOpModeRegister.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright (c) 2014, 2015 Qualcomm Technologies Inc
-
-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 Qualcomm Technologies Inc 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.internal;
-
-import com.qualcomm.robotcore.eventloop.opmode.OpModeManager;
-import com.qualcomm.robotcore.eventloop.opmode.OpModeRegister;
-
-/**
- * {@link FtcOpModeRegister} is responsible for registering OpModes for use in an FTC game.
- * @see #register(OpModeManager)
- */
-public class FtcOpModeRegister implements OpModeRegister {
-
- /**
- * {@link #register(OpModeManager)} is called by the SDK game in order to register
- * OpMode classes or instances that will participate in an FTC game.
- *
- * There are two mechanisms by which an OpMode may be registered.
- *
- * 1) The preferred method is by means of class annotations in the OpMode itself.
- * See, for example the class annotations in {@link org.firstinspires.ftc.robotcontroller.external.samples.ConceptNullOp}.
- *
- * 2) The other, retired, method is to modify this {@link #register(OpModeManager)}
- * method to include explicit calls to OpModeManager.register().
- * This method of modifying this file directly is discouraged, as it
- * makes updates to the SDK harder to integrate into your code.
- *
- * @param manager the object which contains methods for carrying out OpMode registrations
- *
- * @see com.qualcomm.robotcore.eventloop.opmode.TeleOp
- * @see com.qualcomm.robotcore.eventloop.opmode.Autonomous
- */
- public void register(OpModeManager manager) {
-
- /**
- * Any manual OpMode class registrations should go here.
- */
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/FtcRobotControllerActivity.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/FtcRobotControllerActivity.java
deleted file mode 100644
index 3f1f77ce..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/FtcRobotControllerActivity.java
+++ /dev/null
@@ -1,845 +0,0 @@
-/* Copyright (c) 2014, 2015 Qualcomm Technologies Inc
-
-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 Qualcomm Technologies Inc 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.internal;
-
-import android.app.ActionBar;
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.SharedPreferences;
-import android.content.res.Configuration;
-import android.hardware.usb.UsbDevice;
-import android.hardware.usb.UsbManager;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.preference.PreferenceManager;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.WindowManager;
-import android.webkit.WebView;
-import android.widget.ImageButton;
-import android.widget.LinearLayout;
-import android.widget.LinearLayout.LayoutParams;
-import android.widget.PopupMenu;
-import android.widget.TextView;
-
-import com.google.blocks.ftcrobotcontroller.ProgrammingWebHandlers;
-import com.google.blocks.ftcrobotcontroller.runtime.BlocksOpMode;
-import com.qualcomm.ftccommon.ClassManagerFactory;
-import com.qualcomm.ftccommon.FtcAboutActivity;
-import com.qualcomm.ftccommon.FtcEventLoop;
-import com.qualcomm.ftccommon.FtcEventLoopIdle;
-import com.qualcomm.ftccommon.FtcRobotControllerService;
-import com.qualcomm.ftccommon.FtcRobotControllerService.FtcRobotControllerBinder;
-import com.qualcomm.ftccommon.FtcRobotControllerSettingsActivity;
-import com.qualcomm.ftccommon.LaunchActivityConstantsList;
-import com.qualcomm.ftccommon.LaunchActivityConstantsList.RequestCode;
-import com.qualcomm.ftccommon.Restarter;
-import com.qualcomm.ftccommon.UpdateUI;
-import com.qualcomm.ftccommon.configuration.EditParameters;
-import com.qualcomm.ftccommon.configuration.FtcLoadFileActivity;
-import com.qualcomm.ftccommon.configuration.RobotConfigFile;
-import com.qualcomm.ftccommon.configuration.RobotConfigFileManager;
-import com.qualcomm.ftcrobotcontroller.BuildConfig;
-import com.qualcomm.ftcrobotcontroller.R;
-import com.qualcomm.hardware.HardwareFactory;
-import com.qualcomm.robotcore.eventloop.EventLoopManager;
-import com.qualcomm.robotcore.eventloop.opmode.FtcRobotControllerServiceState;
-import com.qualcomm.robotcore.eventloop.opmode.OpModeRegister;
-import com.qualcomm.robotcore.hardware.configuration.LynxConstants;
-import com.qualcomm.robotcore.hardware.configuration.Utility;
-import com.qualcomm.robotcore.robot.Robot;
-import com.qualcomm.robotcore.robot.RobotState;
-import com.qualcomm.robotcore.util.ClockWarningSource;
-import com.qualcomm.robotcore.util.Device;
-import com.qualcomm.robotcore.util.Dimmer;
-import com.qualcomm.robotcore.util.ImmersiveMode;
-import com.qualcomm.robotcore.util.RobotLog;
-import com.qualcomm.robotcore.util.WebServer;
-import com.qualcomm.robotcore.wifi.NetworkConnection;
-import com.qualcomm.robotcore.wifi.NetworkConnectionFactory;
-import com.qualcomm.robotcore.wifi.NetworkType;
-
-import org.firstinspires.ftc.ftccommon.external.SoundPlayingRobotMonitor;
-import org.firstinspires.ftc.ftccommon.internal.AnnotatedHooksClassFilter;
-import org.firstinspires.ftc.ftccommon.internal.FtcRobotControllerWatchdogService;
-import org.firstinspires.ftc.ftccommon.internal.ProgramAndManageActivity;
-import org.firstinspires.ftc.onbotjava.ExternalLibraries;
-import org.firstinspires.ftc.onbotjava.OnBotJavaHelperImpl;
-import org.firstinspires.ftc.onbotjava.OnBotJavaProgrammingMode;
-import org.firstinspires.ftc.robotcore.external.navigation.MotionDetection;
-import org.firstinspires.ftc.robotcore.internal.hardware.android.AndroidBoard;
-import org.firstinspires.ftc.robotcore.internal.network.DeviceNameManagerFactory;
-import org.firstinspires.ftc.robotcore.internal.network.PreferenceRemoterRC;
-import org.firstinspires.ftc.robotcore.internal.network.StartResult;
-import org.firstinspires.ftc.robotcore.internal.network.WifiDirectChannelChanger;
-import org.firstinspires.ftc.robotcore.internal.network.WifiMuteEvent;
-import org.firstinspires.ftc.robotcore.internal.network.WifiMuteStateMachine;
-import org.firstinspires.ftc.robotcore.internal.opmode.ClassManager;
-import org.firstinspires.ftc.robotcore.internal.opmode.OnBotJavaHelper;
-import org.firstinspires.ftc.robotcore.internal.system.AppAliveNotifier;
-import org.firstinspires.ftc.robotcore.internal.system.AppUtil;
-import org.firstinspires.ftc.robotcore.internal.system.Assert;
-import org.firstinspires.ftc.robotcore.internal.system.PreferencesHelper;
-import org.firstinspires.ftc.robotcore.internal.system.ServiceController;
-import org.firstinspires.ftc.robotcore.internal.ui.ThemedActivity;
-import org.firstinspires.ftc.robotcore.internal.ui.UILocation;
-import org.firstinspires.ftc.robotcore.internal.webserver.RobotControllerWebInfo;
-import org.firstinspires.ftc.robotserver.internal.programmingmode.ProgrammingModeManager;
-import org.firstinspires.inspection.RcInspectionActivity;
-import org.threeten.bp.YearMonth;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.FileNotFoundException;
-import java.util.List;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-@SuppressWarnings("WeakerAccess")
-public class FtcRobotControllerActivity extends Activity
- {
- public static final String TAG = "RCActivity";
- public String getTag() { return TAG; }
-
- private static final int REQUEST_CONFIG_WIFI_CHANNEL = 1;
- private static final int NUM_GAMEPADS = 2;
-
- protected WifiManager.WifiLock wifiLock;
- protected RobotConfigFileManager cfgFileMgr;
-
- private OnBotJavaHelper onBotJavaHelper;
-
- protected ProgrammingModeManager programmingModeManager;
-
- protected UpdateUI.Callback callback;
- protected Context context;
- protected Utility utility;
- protected StartResult prefRemoterStartResult = new StartResult();
- protected StartResult deviceNameStartResult = new StartResult();
- protected PreferencesHelper preferencesHelper;
- protected final SharedPreferencesListener sharedPreferencesListener = new SharedPreferencesListener();
-
- protected ImageButton buttonMenu;
- protected TextView textDeviceName;
- protected TextView textNetworkConnectionStatus;
- protected TextView textRobotStatus;
- protected TextView[] textGamepad = new TextView[NUM_GAMEPADS];
- protected TextView textOpMode;
- protected TextView textErrorMessage;
- protected ImmersiveMode immersion;
-
- protected UpdateUI updateUI;
- protected Dimmer dimmer;
- protected LinearLayout entireScreenLayout;
-
- protected FtcRobotControllerService controllerService;
- protected NetworkType networkType;
-
- protected FtcEventLoop eventLoop;
- protected Queue receivedUsbAttachmentNotifications;
-
- protected WifiMuteStateMachine wifiMuteStateMachine;
- protected MotionDetection motionDetection;
-
- private static boolean permissionsValidated = false;
-
- private WifiDirectChannelChanger wifiDirectChannelChanger;
-
- protected class RobotRestarter implements Restarter {
-
- public void requestRestart() {
- requestRobotRestart();
- }
-
- }
-
- protected boolean serviceShouldUnbind = false;
- protected ServiceConnection connection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- FtcRobotControllerBinder binder = (FtcRobotControllerBinder) service;
- onServiceBind(binder.getService());
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- RobotLog.vv(FtcRobotControllerService.TAG, "%s.controllerService=null", TAG);
- controllerService = null;
- }
- };
-
- @Override
- protected void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
-
- if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) {
- UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
- RobotLog.vv(TAG, "ACTION_USB_DEVICE_ATTACHED: %s", usbDevice.getDeviceName());
-
- if (usbDevice != null) { // paranoia
- // We might get attachment notifications before the event loop is set up, so
- // we hold on to them and pass them along only when we're good and ready.
- if (receivedUsbAttachmentNotifications != null) { // *total* paranoia
- receivedUsbAttachmentNotifications.add(usbDevice);
- passReceivedUsbAttachmentsToEventLoop();
- }
- }
- }
- }
-
- protected void passReceivedUsbAttachmentsToEventLoop() {
- if (this.eventLoop != null) {
- for (;;) {
- UsbDevice usbDevice = receivedUsbAttachmentNotifications.poll();
- if (usbDevice == null)
- break;
- this.eventLoop.onUsbDeviceAttached(usbDevice);
- }
- }
- else {
- // Paranoia: we don't want the pending list to grow without bound when we don't
- // (yet) have an event loop
- while (receivedUsbAttachmentNotifications.size() > 100) {
- receivedUsbAttachmentNotifications.poll();
- }
- }
- }
-
- /**
- * There are cases where a permission may be revoked and the system restart will restart the
- * FtcRobotControllerActivity, instead of the launch activity. Detect when that happens, and throw
- * the device back to the permission validator activity.
- */
- protected boolean enforcePermissionValidator() {
- if (!permissionsValidated) {
- RobotLog.vv(TAG, "Redirecting to permission validator");
- Intent permissionValidatorIntent = new Intent(AppUtil.getDefContext(), PermissionValidatorWrapper.class);
- startActivity(permissionValidatorIntent);
- finish();
- return true;
- } else {
- RobotLog.vv(TAG, "Permissions validated already");
- return false;
- }
- }
-
- public static void setPermissionsValidated() {
- permissionsValidated = true;
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- if (enforcePermissionValidator()) {
- return;
- }
-
- RobotLog.onApplicationStart(); // robustify against onCreate() following onDestroy() but using the same app instance, which apparently does happen
- RobotLog.vv(TAG, "onCreate()");
- ThemedActivity.appAppThemeToActivity(getTag(), this); // do this way instead of inherit to help AppInventor
-
- // Oddly, sometimes after a crash & restart the root activity will be something unexpected, like from the before crash? We don't yet understand
- RobotLog.vv(TAG, "rootActivity is of class %s", AppUtil.getInstance().getRootActivity().getClass().getSimpleName());
- RobotLog.vv(TAG, "launchActivity is of class %s", FtcRobotControllerWatchdogService.launchActivity());
- Assert.assertTrue(FtcRobotControllerWatchdogService.isLaunchActivity(AppUtil.getInstance().getRootActivity()));
- Assert.assertTrue(AppUtil.getInstance().isRobotController());
-
- // Quick check: should we pretend we're not here, and so allow the Lynx to operate as
- // a stand-alone USB-connected module?
- if (LynxConstants.isRevControlHub()) {
- // Double-sure check that we can talk to the DB over the serial TTY
- AndroidBoard.getInstance().getAndroidBoardIsPresentPin().setState(true);
- }
-
- context = this;
- utility = new Utility(this);
-
- DeviceNameManagerFactory.getInstance().start(deviceNameStartResult);
-
- PreferenceRemoterRC.getInstance().start(prefRemoterStartResult);
-
- receivedUsbAttachmentNotifications = new ConcurrentLinkedQueue();
- eventLoop = null;
-
- setContentView(R.layout.activity_ftc_controller);
-
- preferencesHelper = new PreferencesHelper(TAG, context);
- preferencesHelper.writeBooleanPrefIfDifferent(context.getString(R.string.pref_rc_connected), true);
- preferencesHelper.getSharedPreferences().registerOnSharedPreferenceChangeListener(sharedPreferencesListener);
-
- // Check if this RC app is from a later FTC season than what was installed previously
- int ftcSeasonYearOfPreviouslyInstalledRc = preferencesHelper.readInt(getString(R.string.pref_ftc_season_year_of_current_rc), 0);
- int ftcSeasonYearOfCurrentlyInstalledRc = AppUtil.getInstance().getFtcSeasonYear(AppUtil.getInstance().getLocalSdkBuildMonth()).getValue();
- if (ftcSeasonYearOfCurrentlyInstalledRc > ftcSeasonYearOfPreviouslyInstalledRc) {
- preferencesHelper.writeIntPrefIfDifferent(getString(R.string.pref_ftc_season_year_of_current_rc), ftcSeasonYearOfCurrentlyInstalledRc);
- // Since it's a new FTC season, we should reset certain settings back to their default values.
- preferencesHelper.writeBooleanPrefIfDifferent(getString(R.string.pref_warn_about_2_4_ghz_band), true);
- preferencesHelper.writeBooleanPrefIfDifferent(getString(R.string.pref_warn_about_obsolete_software), true);
- preferencesHelper.writeBooleanPrefIfDifferent(getString(R.string.pref_warn_about_mismatched_app_versions), true);
- preferencesHelper.writeBooleanPrefIfDifferent(getString(R.string.pref_warn_about_incorrect_clocks), true);
- }
-
- entireScreenLayout = (LinearLayout) findViewById(R.id.entire_screen);
- buttonMenu = (ImageButton) findViewById(R.id.menu_buttons);
- buttonMenu.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- PopupMenu popupMenu = new PopupMenu(FtcRobotControllerActivity.this, v);
- popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- return onOptionsItemSelected(item); // Delegate to the handler for the hardware menu button
- }
- });
- popupMenu.inflate(R.menu.ftc_robot_controller);
- AnnotatedHooksClassFilter.getInstance().callOnCreateMenuMethods(
- FtcRobotControllerActivity.this, popupMenu.getMenu());
- popupMenu.show();
- }
- });
-
- updateMonitorLayout(getResources().getConfiguration());
-
- BlocksOpMode.setActivityAndWebView(this, (WebView) findViewById(R.id.webViewBlocksRuntime));
-
- ExternalLibraries.getInstance().onCreate();
- onBotJavaHelper = new OnBotJavaHelperImpl();
-
- /*
- * Paranoia as the ClassManagerFactory requires EXTERNAL_STORAGE permissions
- * and we've seen on the DS where the finish() call above does not short-circuit
- * the onCreate() call for the activity and then we crash here because we don't
- * have permissions. So...
- */
- if (permissionsValidated) {
- ClassManager.getInstance().setOnBotJavaClassHelper(onBotJavaHelper);
- ClassManagerFactory.registerFilters();
- ClassManagerFactory.processAllClasses();
- }
-
- cfgFileMgr = new RobotConfigFileManager(this);
-
- // Clean up 'dirty' status after a possible crash
- RobotConfigFile configFile = cfgFileMgr.getActiveConfig();
- if (configFile.isDirty()) {
- configFile.markClean();
- cfgFileMgr.setActiveConfig(false, configFile);
- }
-
- textDeviceName = (TextView) findViewById(R.id.textDeviceName);
- textNetworkConnectionStatus = (TextView) findViewById(R.id.textNetworkConnectionStatus);
- textRobotStatus = (TextView) findViewById(R.id.textRobotStatus);
- textOpMode = (TextView) findViewById(R.id.textOpMode);
- textErrorMessage = (TextView) findViewById(R.id.textErrorMessage);
- textGamepad[0] = (TextView) findViewById(R.id.textGamepad1);
- textGamepad[1] = (TextView) findViewById(R.id.textGamepad2);
- immersion = new ImmersiveMode(getWindow().getDecorView());
- dimmer = new Dimmer(this);
- dimmer.longBright();
-
- programmingModeManager = new ProgrammingModeManager();
- programmingModeManager.register(new ProgrammingWebHandlers());
- programmingModeManager.register(new OnBotJavaProgrammingMode());
-
- updateUI = createUpdateUI();
- callback = createUICallback(updateUI);
-
- PreferenceManager.setDefaultValues(this, R.xml.app_settings, false);
-
- WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
- wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "");
-
- hittingMenuButtonBrightensScreen();
-
- wifiLock.acquire();
- callback.networkConnectionUpdate(NetworkConnection.NetworkEvent.DISCONNECTED);
- readNetworkType();
- ServiceController.startService(FtcRobotControllerWatchdogService.class);
- bindToService();
- RobotLog.logAppInfo();
- RobotLog.logDeviceInfo();
- AndroidBoard.getInstance().logAndroidBoardInfo();
-
- if (preferencesHelper.readBoolean(getString(R.string.pref_wifi_automute), false)) {
- initWifiMute(true);
- }
-
- FtcAboutActivity.setBuildTimeFromBuildConfig(BuildConfig.APP_BUILD_TIME);
-
- // check to see if there is a preferred Wi-Fi to use.
- checkPreferredChannel();
-
- AnnotatedHooksClassFilter.getInstance().callOnCreateMethods(this);
- }
-
- protected UpdateUI createUpdateUI() {
- Restarter restarter = new RobotRestarter();
- UpdateUI result = new UpdateUI(this, dimmer);
- result.setRestarter(restarter);
- result.setTextViews(textNetworkConnectionStatus, textRobotStatus, textGamepad, textOpMode, textErrorMessage, textDeviceName);
- return result;
- }
-
- protected UpdateUI.Callback createUICallback(UpdateUI updateUI) {
- UpdateUI.Callback result = updateUI.new Callback();
- result.setStateMonitor(new SoundPlayingRobotMonitor());
- return result;
- }
-
- @Override
- protected void onStart() {
- super.onStart();
- RobotLog.vv(TAG, "onStart()");
-
- entireScreenLayout.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- dimmer.handleDimTimer();
- return false;
- }
- });
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- RobotLog.vv(TAG, "onResume()");
-
- // In case the user just got back from fixing their clock, refresh ClockWarningSource
- ClockWarningSource.getInstance().onPossibleRcClockUpdate();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- RobotLog.vv(TAG, "onPause()");
- }
-
- @Override
- protected void onStop() {
- // Note: this gets called even when the configuration editor is launched. That is, it gets
- // called surprisingly often. So, we don't actually do much here.
- super.onStop();
- RobotLog.vv(TAG, "onStop()");
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- RobotLog.vv(TAG, "onDestroy()");
-
- shutdownRobot(); // Ensure the robot is put away to bed
- if (callback != null) callback.close();
-
- PreferenceRemoterRC.getInstance().stop(prefRemoterStartResult);
- DeviceNameManagerFactory.getInstance().stop(deviceNameStartResult);
-
- unbindFromService();
- // If the app manually (?) is stopped, then we don't need the auto-starting function (?)
- ServiceController.stopService(FtcRobotControllerWatchdogService.class);
- if (wifiLock != null) wifiLock.release();
- if (preferencesHelper != null) preferencesHelper.getSharedPreferences().unregisterOnSharedPreferenceChangeListener(sharedPreferencesListener);
-
- RobotLog.cancelWriteLogcatToDisk();
-
- AnnotatedHooksClassFilter.getInstance().callOnDestroyMethods(this);
- }
-
- protected void bindToService() {
- readNetworkType();
- Intent intent = new Intent(this, FtcRobotControllerService.class);
- intent.putExtra(NetworkConnectionFactory.NETWORK_CONNECTION_TYPE, networkType);
- serviceShouldUnbind = bindService(intent, connection, Context.BIND_AUTO_CREATE);
- }
-
- protected void unbindFromService() {
- if (serviceShouldUnbind) {
- unbindService(connection);
- serviceShouldUnbind = false;
- }
- }
-
- protected void readNetworkType() {
- // Control hubs are always running the access point model. Everything else, for the time
- // being always runs the Wi-Fi Direct model.
- if (Device.isRevControlHub() == true) {
- networkType = NetworkType.RCWIRELESSAP;
- } else {
- networkType = NetworkType.fromString(preferencesHelper.readString(context.getString(R.string.pref_pairing_kind), NetworkType.globalDefaultAsString()));
- }
-
- // update the app_settings
- preferencesHelper.writeStringPrefIfDifferent(context.getString(R.string.pref_pairing_kind), networkType.toString());
- }
-
- @Override
- public void onWindowFocusChanged(boolean hasFocus) {
- super.onWindowFocusChanged(hasFocus);
-
- if (hasFocus) {
- immersion.hideSystemUI();
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.ftc_robot_controller, menu);
- AnnotatedHooksClassFilter.getInstance().callOnCreateMenuMethods(this, menu);
- return true;
- }
-
- private boolean isRobotRunning() {
- if (controllerService == null) {
- return false;
- }
-
- Robot robot = controllerService.getRobot();
-
- if ((robot == null) || (robot.eventLoopManager == null)) {
- return false;
- }
-
- RobotState robotState = robot.eventLoopManager.state;
-
- if (robotState != RobotState.RUNNING) {
- return false;
- } else {
- return true;
- }
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- int id = item.getItemId();
-
- if (id == R.id.action_program_and_manage) {
- if (isRobotRunning()) {
- Intent programmingModeIntent = new Intent(AppUtil.getDefContext(), ProgramAndManageActivity.class);
- RobotControllerWebInfo webInfo = programmingModeManager.getWebServer().getConnectionInformation();
- programmingModeIntent.putExtra(LaunchActivityConstantsList.RC_WEB_INFO, webInfo.toJson());
- startActivity(programmingModeIntent);
- } else {
- AppUtil.getInstance().showToast(UILocation.ONLY_LOCAL, context.getString(R.string.toastWifiUpBeforeProgrammingMode));
- }
- } else if (id == R.id.action_inspection_mode) {
- Intent inspectionModeIntent = new Intent(AppUtil.getDefContext(), RcInspectionActivity.class);
- startActivity(inspectionModeIntent);
- return true;
- } else if (id == R.id.action_restart_robot) {
- dimmer.handleDimTimer();
- AppUtil.getInstance().showToast(UILocation.BOTH, context.getString(R.string.toastRestartingRobot));
- requestRobotRestart();
- return true;
- }
- else if (id == R.id.action_configure_robot) {
- EditParameters parameters = new EditParameters();
- Intent intentConfigure = new Intent(AppUtil.getDefContext(), FtcLoadFileActivity.class);
- parameters.putIntent(intentConfigure);
- startActivityForResult(intentConfigure, RequestCode.CONFIGURE_ROBOT_CONTROLLER.ordinal());
- }
- else if (id == R.id.action_settings) {
- // historical: this once erroneously used FTC_CONFIGURE_REQUEST_CODE_ROBOT_CONTROLLER
- Intent settingsIntent = new Intent(AppUtil.getDefContext(), FtcRobotControllerSettingsActivity.class);
- startActivityForResult(settingsIntent, RequestCode.SETTINGS_ROBOT_CONTROLLER.ordinal());
- return true;
- }
- else if (id == R.id.action_about) {
- Intent intent = new Intent(AppUtil.getDefContext(), FtcAboutActivity.class);
- startActivity(intent);
- return true;
- }
- else if (id == R.id.action_exit_app) {
-
- //Clear backstack and everything to prevent edge case where VM might be
- //restarted (after it was exited) if more than one activity was on the
- //backstack for some reason.
- finishAffinity();
-
- //For lollipop and up, we can clear ourselves from the recents list too
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
- ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
- List tasks = manager.getAppTasks();
-
- for (ActivityManager.AppTask task : tasks) {
- task.finishAndRemoveTask();
- }
- }
-
- // Allow the user to use the Control Hub operating system's UI, instead of relaunching the app
- AppAliveNotifier.getInstance().disableAppWatchdogUntilNextAppStart();
-
- //Finally, nuke the VM from orbit
- AppUtil.getInstance().exitApplication();
-
- return true;
- }
-
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- // don't destroy assets on screen rotation
- updateMonitorLayout(newConfig);
- }
-
- /**
- * Updates the orientation of monitorContainer (which contains cameraMonitorView)
- * based on the given configuration. Makes the children split the space.
- */
- private void updateMonitorLayout(Configuration configuration) {
- LinearLayout monitorContainer = (LinearLayout) findViewById(R.id.monitorContainer);
- if (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
- // When the phone is landscape, lay out the monitor views horizontally.
- monitorContainer.setOrientation(LinearLayout.HORIZONTAL);
- for (int i = 0; i < monitorContainer.getChildCount(); i++) {
- View view = monitorContainer.getChildAt(i);
- view.setLayoutParams(new LayoutParams(0, LayoutParams.MATCH_PARENT, 1 /* weight */));
- }
- } else {
- // When the phone is portrait, lay out the monitor views vertically.
- monitorContainer.setOrientation(LinearLayout.VERTICAL);
- for (int i = 0; i < monitorContainer.getChildCount(); i++) {
- View view = monitorContainer.getChildAt(i);
- view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 0, 1 /* weight */));
- }
- }
- monitorContainer.requestLayout();
- }
-
- @Override
- protected void onActivityResult(int request, int result, Intent intent) {
- if (request == REQUEST_CONFIG_WIFI_CHANNEL) {
- if (result == RESULT_OK) {
- AppUtil.getInstance().showToast(UILocation.BOTH, context.getString(R.string.toastWifiConfigurationComplete));
- }
- }
- // was some historical confusion about launch codes here, so we err safely
- if (request == RequestCode.CONFIGURE_ROBOT_CONTROLLER.ordinal() || request == RequestCode.SETTINGS_ROBOT_CONTROLLER.ordinal()) {
- // We always do a refresh, whether it was a cancel or an OK, for robustness
- shutdownRobot();
- cfgFileMgr.getActiveConfigAndUpdateUI();
- updateUIAndRequestRobotSetup();
- }
- }
-
- public void onServiceBind(final FtcRobotControllerService service) {
- RobotLog.vv(FtcRobotControllerService.TAG, "%s.controllerService=bound", TAG);
- controllerService = service;
- updateUI.setControllerService(controllerService);
-
- controllerService.setOnBotJavaHelper(onBotJavaHelper);
-
- updateUIAndRequestRobotSetup();
- programmingModeManager.setState(new FtcRobotControllerServiceState() {
- @NonNull
- @Override
- public WebServer getWebServer() {
- return service.getWebServer();
- }
-
- @Nullable
- @Override
- public OnBotJavaHelper getOnBotJavaHelper() {
- return service.getOnBotJavaHelper();
- }
-
- @Override
- public EventLoopManager getEventLoopManager() {
- return service.getRobot().eventLoopManager;
- }
- });
-
- AnnotatedHooksClassFilter.getInstance().callWebHandlerRegistrarMethods(this,
- service.getWebServer().getWebHandlerManager());
- }
-
- private void updateUIAndRequestRobotSetup() {
- if (controllerService != null) {
- callback.networkConnectionUpdate(controllerService.getNetworkConnectionStatus());
- callback.updateRobotStatus(controllerService.getRobotStatus());
- // Only show this first-time toast on headless systems: what we have now on non-headless suffices
- requestRobotSetup(LynxConstants.isRevControlHub()
- ? new Runnable() {
- @Override public void run() {
- showRestartRobotCompleteToast(R.string.toastRobotSetupComplete);
- }
- }
- : null);
- }
- }
-
- private void requestRobotSetup(@Nullable Runnable runOnComplete) {
- if (controllerService == null) return;
-
- RobotConfigFile file = cfgFileMgr.getActiveConfigAndUpdateUI();
- HardwareFactory hardwareFactory = new HardwareFactory(context);
- try {
- hardwareFactory.setXmlPullParser(file.getXml());
- } catch (FileNotFoundException | XmlPullParserException e) {
- RobotLog.ww(TAG, e, "Unable to set configuration file %s. Falling back on noConfig.", file.getName());
- file = RobotConfigFile.noConfig(cfgFileMgr);
- try {
- hardwareFactory.setXmlPullParser(file.getXml());
- cfgFileMgr.setActiveConfigAndUpdateUI(false, file);
- } catch (FileNotFoundException | XmlPullParserException e1) {
- RobotLog.ee(TAG, e1, "Failed to fall back on noConfig");
- }
- }
-
- OpModeRegister userOpModeRegister = createOpModeRegister();
- eventLoop = new FtcEventLoop(hardwareFactory, userOpModeRegister, callback, this);
- FtcEventLoopIdle idleLoop = new FtcEventLoopIdle(hardwareFactory, userOpModeRegister, callback, this);
-
- controllerService.setCallback(callback);
- controllerService.setupRobot(eventLoop, idleLoop, runOnComplete);
-
- passReceivedUsbAttachmentsToEventLoop();
- AndroidBoard.showErrorIfUnknownControlHub();
-
- AnnotatedHooksClassFilter.getInstance().callOnCreateEventLoopMethods(this, eventLoop);
- }
-
- protected OpModeRegister createOpModeRegister() {
- return new FtcOpModeRegister();
- }
-
- private void shutdownRobot() {
- if (controllerService != null) controllerService.shutdownRobot();
- }
-
- private void requestRobotRestart() {
- AppUtil.getInstance().showToast(UILocation.BOTH, AppUtil.getDefContext().getString(R.string.toastRestartingRobot));
- //
- RobotLog.clearGlobalErrorMsg();
- RobotLog.clearGlobalWarningMsg();
- shutdownRobot();
- requestRobotSetup(new Runnable() {
- @Override public void run() {
- showRestartRobotCompleteToast(R.string.toastRestartRobotComplete);
- }
- });
- }
-
- private void showRestartRobotCompleteToast(@StringRes int resid) {
- AppUtil.getInstance().showToast(UILocation.BOTH, AppUtil.getDefContext().getString(resid));
- }
-
- private void checkPreferredChannel() {
- // For P2P network, check to see what preferred channel is.
- if (networkType == NetworkType.WIFIDIRECT) {
- int prefChannel = preferencesHelper.readInt(getString(com.qualcomm.ftccommon.R.string.pref_wifip2p_channel), -1);
- if (prefChannel == -1) {
- prefChannel = 0;
- RobotLog.vv(TAG, "pref_wifip2p_channel: No preferred channel defined. Will use a default value of %d", prefChannel);
- } else {
- RobotLog.vv(TAG, "pref_wifip2p_channel: Found existing preferred channel (%d).", prefChannel);
- }
-
- // attempt to set the preferred channel.
- RobotLog.vv(TAG, "pref_wifip2p_channel: attempting to set preferred channel...");
- wifiDirectChannelChanger = new WifiDirectChannelChanger();
- wifiDirectChannelChanger.changeToChannel(prefChannel);
- }
- }
-
- protected void hittingMenuButtonBrightensScreen() {
- ActionBar actionBar = getActionBar();
- if (actionBar != null) {
- actionBar.addOnMenuVisibilityListener(new ActionBar.OnMenuVisibilityListener() {
- @Override
- public void onMenuVisibilityChanged(boolean isVisible) {
- if (isVisible) {
- dimmer.handleDimTimer();
- }
- }
- });
- }
- }
-
- protected class SharedPreferencesListener implements SharedPreferences.OnSharedPreferenceChangeListener {
- @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- if (key.equals(context.getString(R.string.pref_app_theme))) {
- ThemedActivity.restartForAppThemeChange(getTag(), getString(R.string.appThemeChangeRestartNotifyRC));
- } else if (key.equals(context.getString(R.string.pref_wifi_automute))) {
- if (preferencesHelper.readBoolean(context.getString(R.string.pref_wifi_automute), false)) {
- initWifiMute(true);
- } else {
- initWifiMute(false);
- }
- }
- }
- }
-
- protected void initWifiMute(boolean enable) {
- if (enable) {
- wifiMuteStateMachine = new WifiMuteStateMachine();
- wifiMuteStateMachine.initialize();
- wifiMuteStateMachine.start();
-
- motionDetection = new MotionDetection(2.0, 10);
- motionDetection.startListening();
- motionDetection.registerListener(new MotionDetection.MotionDetectionListener() {
- @Override
- public void onMotionDetected(double vector)
- {
- wifiMuteStateMachine.consumeEvent(WifiMuteEvent.USER_ACTIVITY);
- }
- });
- } else {
- wifiMuteStateMachine.stop();
- wifiMuteStateMachine = null;
- motionDetection.stopListening();
- motionDetection.purgeListeners();
- motionDetection = null;
- }
- }
-
- @Override
- public void onUserInteraction() {
- if (wifiMuteStateMachine != null) {
- wifiMuteStateMachine.consumeEvent(WifiMuteEvent.USER_ACTIVITY);
- }
- }
-}
diff --git a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/PermissionValidatorWrapper.java b/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/PermissionValidatorWrapper.java
deleted file mode 100644
index a0094bc9..00000000
--- a/examples/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/PermissionValidatorWrapper.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2018 Craig MacFarlane
- *
- * 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 Craig MacFarlane 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.internal;
-
-import android.Manifest;
-import android.os.Bundle;
-
-import com.qualcomm.ftcrobotcontroller.R;
-
-import org.firstinspires.ftc.robotcore.internal.system.Misc;
-import org.firstinspires.ftc.robotcore.internal.system.PermissionValidatorActivity;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PermissionValidatorWrapper extends PermissionValidatorActivity {
-
- private final String TAG = "PermissionValidatorWrapper";
-
- /*
- * The list of dangerous permissions the robot controller needs.
- */
- protected List robotControllerPermissions = new ArrayList() {{
- add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
- add(Manifest.permission.READ_EXTERNAL_STORAGE);
- add(Manifest.permission.CAMERA);
- add(Manifest.permission.ACCESS_COARSE_LOCATION);
- add(Manifest.permission.ACCESS_FINE_LOCATION);
- add(Manifest.permission.READ_PHONE_STATE);
- }};
-
- private final static Class startApplication = FtcRobotControllerActivity.class;
-
- public String mapPermissionToExplanation(final String permission) {
- if (permission.equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
- return Misc.formatForUser(R.string.permRcWriteExternalStorageExplain);
- } else if (permission.equals(Manifest.permission.READ_EXTERNAL_STORAGE)) {
- return Misc.formatForUser(R.string.permRcReadExternalStorageExplain);
- } else if (permission.equals(Manifest.permission.CAMERA)) {
- return Misc.formatForUser(R.string.permRcCameraExplain);
- } else if (permission.equals(Manifest.permission.ACCESS_COARSE_LOCATION)) {
- return Misc.formatForUser(R.string.permAccessLocationExplain);
- } else if (permission.equals(Manifest.permission.ACCESS_FINE_LOCATION)) {
- return Misc.formatForUser(R.string.permAccessLocationExplain);
- } else if (permission.equals(Manifest.permission.READ_PHONE_STATE)) {
- return Misc.formatForUser(R.string.permReadPhoneState);
- }
- return Misc.formatForUser(R.string.permGenericExplain);
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
-
- permissions = robotControllerPermissions;
- }
-
- protected Class onStartApplication()
- {
- FtcRobotControllerActivity.setPermissionsValidated();
- return startApplication;
- }
-}
diff --git a/examples/FtcRobotController/src/main/res/drawable-xhdpi/icon_menu.png b/examples/FtcRobotController/src/main/res/drawable-xhdpi/icon_menu.png
deleted file mode 100644
index 6b9e997c..00000000
Binary files a/examples/FtcRobotController/src/main/res/drawable-xhdpi/icon_menu.png and /dev/null differ
diff --git a/examples/FtcRobotController/src/main/res/drawable-xhdpi/icon_robotcontroller.png b/examples/FtcRobotController/src/main/res/drawable-xhdpi/icon_robotcontroller.png
deleted file mode 100644
index 022552f4..00000000
Binary files a/examples/FtcRobotController/src/main/res/drawable-xhdpi/icon_robotcontroller.png and /dev/null differ
diff --git a/examples/FtcRobotController/src/main/res/layout/activity_ftc_controller.xml b/examples/FtcRobotController/src/main/res/layout/activity_ftc_controller.xml
deleted file mode 100644
index 6524f948..00000000
--- a/examples/FtcRobotController/src/main/res/layout/activity_ftc_controller.xml
+++ /dev/null
@@ -1,184 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/FtcRobotController/src/main/res/menu/ftc_robot_controller.xml b/examples/FtcRobotController/src/main/res/menu/ftc_robot_controller.xml
deleted file mode 100644
index 657c1aac..00000000
--- a/examples/FtcRobotController/src/main/res/menu/ftc_robot_controller.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-
-
-
diff --git a/examples/FtcRobotController/src/main/res/raw/gold.wav b/examples/FtcRobotController/src/main/res/raw/gold.wav
deleted file mode 100644
index 3a7baf88..00000000
Binary files a/examples/FtcRobotController/src/main/res/raw/gold.wav and /dev/null differ
diff --git a/examples/FtcRobotController/src/main/res/raw/silver.wav b/examples/FtcRobotController/src/main/res/raw/silver.wav
deleted file mode 100644
index 25918a72..00000000
Binary files a/examples/FtcRobotController/src/main/res/raw/silver.wav and /dev/null differ
diff --git a/examples/FtcRobotController/src/main/res/values/dimens.xml b/examples/FtcRobotController/src/main/res/values/dimens.xml
deleted file mode 100644
index 63f1babc..00000000
--- a/examples/FtcRobotController/src/main/res/values/dimens.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
- 16dp
- 5dp
-
-
\ No newline at end of file
diff --git a/examples/FtcRobotController/src/main/res/values/strings.xml b/examples/FtcRobotController/src/main/res/values/strings.xml
deleted file mode 100644
index 6ea191ed..00000000
--- a/examples/FtcRobotController/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-
-
-
-
- FTC Robot Controller
-
-
- Self Inspect
- Program & Manage
- Blocks
- Settings
- Restart Robot
- Configure Robot
- About
- Exit
-
-
- Configuration Complete
- Restarting Robot
- The Robot Controller must be fully up and running before entering Program and Manage Mode.
-
-
-
- - @style/AppThemeRedRC
- - @style/AppThemeGreenRC
- - @style/AppThemeBlueRC
- - @style/AppThemePurpleRC
- - @style/AppThemeOrangeRC
- - @style/AppThemeTealRC
-
-
- pref_ftc_season_year_of_current_rc_new
-
- @string/packageNameRobotController
-
-
diff --git a/examples/FtcRobotController/src/main/res/values/styles.xml b/examples/FtcRobotController/src/main/res/values/styles.xml
deleted file mode 100644
index 07689c03..00000000
--- a/examples/FtcRobotController/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/FtcRobotController/src/main/res/xml/app_settings.xml b/examples/FtcRobotController/src/main/res/xml/app_settings.xml
deleted file mode 100644
index 58d3aa9c..00000000
--- a/examples/FtcRobotController/src/main/res/xml/app_settings.xml
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/FtcRobotController/src/main/res/xml/device_filter.xml b/examples/FtcRobotController/src/main/res/xml/device_filter.xml
deleted file mode 100644
index 7b75350c..00000000
--- a/examples/FtcRobotController/src/main/res/xml/device_filter.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/TeamCode/build.gradle b/examples/TeamCode/build.gradle
deleted file mode 100644
index ffd499bf..00000000
--- a/examples/TeamCode/build.gradle
+++ /dev/null
@@ -1,47 +0,0 @@
-//
-// build.gradle in TeamCode
-//
-// Most of the definitions for building your module reside in a common, shared
-// file 'build.common.gradle'. Being factored in this way makes it easier to
-// integrate updates to the FTC into your code. If you really need to customize
-// the build definitions, you can place those customizations in this file, but
-// please think carefully as to whether such customizations are really necessary
-// before doing so.
-
-
-// Custom definitions may go here
-
-// Include common definitions from above.
-apply from: '../build.common.gradle'
-apply from: '../build.dependencies.gradle'
-apply plugin: 'org.jetbrains.kotlin.android'
-
-android {
- namespace = 'org.firstinspires.ftc.teamcode'
-
- defaultConfig {
- compileSdk = 35
- minSdk = 24
- }
-
- packagingOptions {
- jniLibs.useLegacyPackaging true
- }
-
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_11
- targetCompatibility JavaVersion.VERSION_11
- }
- kotlinOptions {
- jvmTarget = '11'
- }
-}
-
-repositories {
-}
-
-dependencies {
- implementation project(':FtcRobotController')
- implementation project(':FullPanels')
- implementation project(':ExamplePlugin')
-}
diff --git a/examples/TeamCode/lib/OpModeAnnotationProcessor.jar b/examples/TeamCode/lib/OpModeAnnotationProcessor.jar
deleted file mode 100644
index 4825cc36..00000000
Binary files a/examples/TeamCode/lib/OpModeAnnotationProcessor.jar and /dev/null differ
diff --git a/examples/build.common.gradle b/examples/build.common.gradle
deleted file mode 100644
index 78f29e83..00000000
--- a/examples/build.common.gradle
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
- * build.common.gradle
- *
- * Try to avoid editing this file, as it may be updated from time to time as the FTC SDK
- * evolves. Rather, if it is necessary to customize the build process, do those edits in
- * the build.gradle file in TeamCode.
- *
- * This file contains the necessary content of the 'build.gradle' files for robot controller
- * applications built using the FTC SDK. Each individual 'build.gradle' in those applications
- * can simply contain the one line:
- *
- * apply from: '../build.common.gradle'
- *
- * which will pick up this file here. This approach allows makes it easier to integrate
- * updates to the FTC SDK into your code.
- */
-
-import java.util.regex.Pattern
-
-apply plugin: 'com.android.application'
-
-android {
-
- compileSdkVersion 30
-
- signingConfigs {
- release {
- def apkStoreFile = System.getenv("APK_SIGNING_STORE_FILE")
- if (apkStoreFile != null) {
- keyAlias System.getenv("APK_SIGNING_KEY_ALIAS")
- keyPassword System.getenv("APK_SIGNING_KEY_PASSWORD")
- storeFile file(System.getenv("APK_SIGNING_STORE_FILE"))
- storePassword System.getenv("APK_SIGNING_STORE_PASSWORD")
- } else {
- keyAlias 'androiddebugkey'
- keyPassword 'android'
- storeFile rootProject.file('libs/ftc.debug.keystore')
- storePassword 'android'
- }
- }
-
- debug {
- keyAlias 'androiddebugkey'
- keyPassword 'android'
- storeFile rootProject.file('libs/ftc.debug.keystore')
- storePassword 'android'
- }
- }
-
- defaultConfig {
- signingConfig signingConfigs.debug
- applicationId 'com.qualcomm.ftcrobotcontroller'
- minSdkVersion 25
- //noinspection ExpiredTargetSdkVersion
- targetSdkVersion 28
-
- /**
- * We keep the versionCode and versionName of robot controller applications in sync with
- * the master information published in the AndroidManifest.xml file of the FtcRobotController
- * module. This helps avoid confusion that might arise from having multiple versions of
- * a robot controller app simultaneously installed on a robot controller device.
- *
- * We accomplish this with the help of a funky little Groovy script that maintains that
- * correspondence automatically.
- *
- * @see Configure Your Build
- * @see Versioning Your App
- */
- def manifestFile = project(':FtcRobotController').file('src/main/AndroidManifest.xml');
- def manifestText = manifestFile.getText()
- //
- def vCodePattern = Pattern.compile("versionCode=\"(\\d+(\\.\\d+)*)\"")
- def matcher = vCodePattern.matcher(manifestText)
- matcher.find()
- def vCode = Integer.parseInt(matcher.group(1))
- //
- def vNamePattern = Pattern.compile("versionName=\"(.*)\"")
- matcher = vNamePattern.matcher(manifestText);
- matcher.find()
- def vName = matcher.group(1)
- //
- versionCode vCode
- versionName vName
- }
-
- // http://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.BuildType.html
- buildTypes {
- release {
- signingConfig signingConfigs.release
-
- ndk {
- abiFilters "armeabi-v7a", "arm64-v8a"
- }
- }
- debug {
- debuggable true
- jniDebuggable true
- ndk {
- abiFilters "armeabi-v7a", "arm64-v8a"
- }
- }
- }
-
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
-
- packagingOptions {
- pickFirst '**/*.so'
- }
- ndkVersion '21.3.6528147'
-}
-
-repositories {
-}
-
diff --git a/examples/build.dependencies.gradle b/examples/build.dependencies.gradle
deleted file mode 100644
index 1c07e8cb..00000000
--- a/examples/build.dependencies.gradle
+++ /dev/null
@@ -1,17 +0,0 @@
-repositories {
- mavenCentral()
- google() // Needed for androidx
-}
-
-dependencies {
- implementation 'org.firstinspires.ftc:Inspection:11.0.0'
- implementation 'org.firstinspires.ftc:Blocks:11.0.0'
- implementation 'org.firstinspires.ftc:RobotCore:11.0.0'
- implementation 'org.firstinspires.ftc:RobotServer:11.0.0'
- implementation 'org.firstinspires.ftc:OnBotJava:11.0.0'
- implementation 'org.firstinspires.ftc:Hardware:11.0.0'
- implementation 'org.firstinspires.ftc:FtcCommon:11.0.0'
- implementation 'org.firstinspires.ftc:Vision:11.0.0'
- implementation 'androidx.appcompat:appcompat:1.2.0'
-}
-
diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts
index 44ecb6e2..dc622281 100644
--- a/examples/build.gradle.kts
+++ b/examples/build.gradle.kts
@@ -1,33 +1,11 @@
-/**
- * Top-level build file for ftc_app project.
- *
- * It is extraordinarily rare that you will ever need to edit this file.
- */
-
-buildscript {
- val kotlin_version by extra("2.1.20")
-
- repositories {
- mavenCentral()
- google()
- }
-
- dependencies {
- // Note for FTC Teams: Do not modify this yourself.
- classpath("com.android.tools.build:gradle:8.7.0")
- classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
- }
+plugins {
+ id("dev.frozenmilk.teamcode") version "11.1.0-1.1.1"
}
-// This is now required because aapt2 has to be downloaded from the
-// google() repository beginning with version 3.2 of the Android Gradle Plugin
-allprojects {
- repositories {
- mavenCentral()
- google()
+ftc {
+ kotlin()
+ sdk.TeamCode()
+ dairy.ftControl {
+ implementation(fullpanels(""))
}
}
-
-repositories {
- mavenCentral()
-}
diff --git a/examples/gradle.properties b/examples/gradle.properties
index f5935e91..8867ee4c 100644
--- a/examples/gradle.properties
+++ b/examples/gradle.properties
@@ -9,4 +9,7 @@ android.enableJetifier=false
# Allow Gradle to use up to 1 GB of RAM
org.gradle.jvmargs=-Xmx1024M
-android.nonTransitiveRClass=false
\ No newline at end of file
+android.nonTransitiveRClass=false
+
+org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled
+org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true
\ No newline at end of file
diff --git a/examples/gradlew b/examples/gradlew
old mode 100644
new mode 100755
diff --git a/examples/settings.gradle.kts b/examples/settings.gradle.kts
index 3ef085d5..bff3fad7 100644
--- a/examples/settings.gradle.kts
+++ b/examples/settings.gradle.kts
@@ -1,7 +1,9 @@
pluginManagement {
- includeBuild("../library/plugin-svelte-assets")
repositories {
gradlePluginPortal()
+ mavenCentral()
+ google()
+ maven("https://repo.dairy.foundation/releases")
}
}
@@ -28,10 +30,14 @@ val modules = listOf(
"CameraStream"
)
-modules.forEach { name ->
- include(":$name")
- project(":$name").projectDir = file("../library/$name")
-}
+//modules.forEach { name ->
+// include(":$name")
+// project(":$name").projectDir = file("../library/$name")
+//}
-include(":FtcRobotController")
-include(":TeamCode")
\ No newline at end of file
+includeBuild("../library") {
+ dependencySubstitution {
+ substitute(module("com.bylazar.sloth:fullpanels")).using(project(":FullPanels"))
+ substitute(module("com.bylazar:fullpanels")).using(project(":FullPanels"))
+ }
+}
\ No newline at end of file
diff --git a/examples/TeamCode/src/main/AndroidManifest.xml b/examples/src/main/AndroidManifest.xml
similarity index 100%
rename from examples/TeamCode/src/main/AndroidManifest.xml
rename to examples/src/main/AndroidManifest.xml
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/ClawConfig.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/ClawConfig.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/ClawConfig.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/ClawConfig.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/Config.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/Config.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/Config.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/Config.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/Drawing.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/Drawing.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/Drawing.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/Drawing.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/TestConfigurables.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/TestConfigurables.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/TestConfigurables.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/TestConfigurables.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/TestConfigurablesValues.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/TestConfigurablesValues.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/TestConfigurablesValues.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/TestConfigurablesValues.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/TestKotlinObject.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/TestKotlinObject.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/TestKotlinObject.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/TestKotlinObject.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/TestTelemetry.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/TestTelemetry.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/TestTelemetry.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/TestTelemetry.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/battery/BatteryExample.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/battery/BatteryExample.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/battery/BatteryExample.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/battery/BatteryExample.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/camerastream/TestCameraStream.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/camerastream/TestCameraStream.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/camerastream/TestCameraStream.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/camerastream/TestCameraStream.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/ClawConfig.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/ClawConfig.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/ClawConfig.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/ClawConfig.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/JavaRobotConstants.java b/examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/JavaRobotConstants.java
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/JavaRobotConstants.java
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/JavaRobotConstants.java
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/KotlinRobotConstants.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/KotlinRobotConstants.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/KotlinRobotConstants.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/KotlinRobotConstants.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/SortedConfigurables.java b/examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/SortedConfigurables.java
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/SortedConfigurables.java
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/SortedConfigurables.java
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/TestJavaClass.java b/examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/TestJavaClass.java
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/TestJavaClass.java
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/TestJavaClass.java
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/TestKotlinClass.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/TestKotlinClass.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/TestKotlinClass.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/TestKotlinClass.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/TestKotlinObject.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/TestKotlinObject.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/TestKotlinObject.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/TestKotlinObject.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/TestOpMode.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/TestOpMode.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/TestOpMode.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/TestOpMode.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/copysemantics/bad/Example.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/copysemantics/bad/Example.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/copysemantics/bad/Example.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/copysemantics/bad/Example.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/copysemantics/fixed/Example.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/copysemantics/fixed/Example.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/copysemantics/fixed/Example.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/copysemantics/fixed/Example.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/copysemantics/lambda/Example.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/copysemantics/lambda/Example.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/configurables/copysemantics/lambda/Example.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/configurables/copysemantics/lambda/Example.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/field/BezierFollower.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/field/BezierFollower.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/field/BezierFollower.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/field/BezierFollower.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/field/CustomPresets.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/field/CustomPresets.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/field/CustomPresets.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/field/CustomPresets.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/field/Drawing.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/field/Drawing.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/field/Drawing.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/field/Drawing.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/field/TestCoords.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/field/TestCoords.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/field/TestCoords.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/field/TestCoords.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/gamepad/TestGamepad.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/gamepad/TestGamepad.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/gamepad/TestGamepad.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/gamepad/TestGamepad.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/graph/TestGraph.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/graph/TestGraph.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/graph/TestGraph.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/graph/TestGraph.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/lights/TestLights.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/lights/TestLights.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/lights/TestLights.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/lights/TestLights.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/opmodecontrol/TimerTest.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/opmodecontrol/TimerTest.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/opmodecontrol/TimerTest.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/opmodecontrol/TimerTest.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/readme.md b/examples/src/main/java/org/firstinspires/ftc/teamcode/readme.md
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/readme.md
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/readme.md
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/telemetry/TestFormatTelemetry.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/telemetry/TestFormatTelemetry.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/telemetry/TestFormatTelemetry.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/telemetry/TestFormatTelemetry.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/telemetry/TestJoinedTelemetry.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/telemetry/TestJoinedTelemetry.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/telemetry/TestJoinedTelemetry.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/telemetry/TestJoinedTelemetry.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/telemetry/TestTelemetryFTCStyle.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/telemetry/TestTelemetryFTCStyle.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/telemetry/TestTelemetryFTCStyle.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/telemetry/TestTelemetryFTCStyle.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/telemetry/TestTelemetryPanelsStyle.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/telemetry/TestTelemetryPanelsStyle.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/telemetry/TestTelemetryPanelsStyle.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/telemetry/TestTelemetryPanelsStyle.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/utils/LoopTimerExample.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/utils/LoopTimerExample.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/utils/LoopTimerExample.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/utils/LoopTimerExample.kt
diff --git a/examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/utils/MovingAverageExample.kt b/examples/src/main/java/org/firstinspires/ftc/teamcode/utils/MovingAverageExample.kt
similarity index 100%
rename from examples/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/utils/MovingAverageExample.kt
rename to examples/src/main/java/org/firstinspires/ftc/teamcode/utils/MovingAverageExample.kt
diff --git a/examples/TeamCode/src/main/res/raw/readme.md b/examples/src/main/res/raw/readme.md
similarity index 100%
rename from examples/TeamCode/src/main/res/raw/readme.md
rename to examples/src/main/res/raw/readme.md
diff --git a/examples/TeamCode/src/main/res/values/strings.xml b/examples/src/main/res/values/strings.xml
similarity index 100%
rename from examples/TeamCode/src/main/res/values/strings.xml
rename to examples/src/main/res/values/strings.xml
diff --git a/examples/TeamCode/src/main/res/xml/teamwebcamcalibrations.xml b/examples/src/main/res/xml/teamwebcamcalibrations.xml
similarity index 100%
rename from examples/TeamCode/src/main/res/xml/teamwebcamcalibrations.xml
rename to examples/src/main/res/xml/teamwebcamcalibrations.xml
diff --git a/library/.gitignore b/library/.gitignore
index 8ea3a652..e9b0d3c9 100644
--- a/library/.gitignore
+++ b/library/.gitignore
@@ -1,5 +1,6 @@
# dependencies (rm -rf bun.lock && bun install --no-cachenstall)
node_modules
+.bun
# output
out
diff --git a/library/Battery/build.gradle.kts b/library/Battery/build.gradle.kts
index f5bbe506..5f7fbbfa 100644
--- a/library/Battery/build.gradle.kts
+++ b/library/Battery/build.gradle.kts
@@ -2,56 +2,46 @@ val pluginNamespace = "com.bylazar.battery"
val pluginVersion = "1.0.3"
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("maven-publish")
+ id("dev.frozenmilk.android-library") version "11.1.0-1.1.1"
id("com.bylazar.svelte-assets")
+ id("dev.frozenmilk.publish") version "0.0.5"
+ id("dev.frozenmilk.doc") version "0.0.5"
+ id("dev.frozenmilk.build-meta-data") version "0.0.2"
}
+android.namespace = pluginNamespace
+
svelteAssets {
- webAppPath = "web"
- buildDirPath = "dist"
- assetsPath = "web/plugins/$pluginNamespace"
+ assetsPath = assetPathForPlugin(pluginNamespace)
}
-android {
- namespace = pluginNamespace
-
- defaultConfig {
- compileSdk = 34
- minSdk = 24
- }
-
- buildTypes {
- getByName("release") {
- isMinifyEnabled = false
- }
- }
+dairyPublishing {
+ gitDir = file("..")
+}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- }
+version = "${dairyPublishing.version}+$pluginVersion"
- kotlinOptions {
- jvmTarget = "11"
- }
+meta {
+ packagePath = pluginNamespace
+ name = "Battery"
+ registerField("name", "String", "\"$pluginNamespace\"")
+ registerField("clean", "Boolean") { "${dairyPublishing.clean}" }
+ registerField("gitRef", "String") { "\"${dairyPublishing.gitRef}\"" }
+ registerField("snapshot", "Boolean") { "${dairyPublishing.snapshot}" }
+ registerField("version", "String") { "\"$version\"" }
+}
- publishing {
- singleVariant("release") {}
+ftc {
+ kotlin()
+ sdk {
+ compileOnly(RobotCore)
+ compileOnly(FtcCommon)
+ compileOnly(RobotServer)
+ compileOnly(Hardware)
}
}
dependencies {
- compileOnly("org.firstinspires.ftc:Inspection:11.0.0")
- compileOnly("org.firstinspires.ftc:Blocks:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotCore:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotServer:11.0.0")
- compileOnly("org.firstinspires.ftc:OnBotJava:11.0.0")
- compileOnly("org.firstinspires.ftc:Hardware:11.0.0")
- compileOnly("org.firstinspires.ftc:FtcCommon:11.0.0")
- compileOnly("org.firstinspires.ftc:Vision:11.0.0")
-
compileOnly(project(":Panels"))
}
@@ -61,9 +51,11 @@ afterEvaluate {
create("release") {
from(components["release"])
- groupId = pluginNamespace.substringBeforeLast('.')
+ groupId = pluginNamespace.substringBeforeLast('.') + ".sloth"
artifactId = pluginNamespace.substringAfterLast('.')
- version = pluginVersion
+
+ artifact(dairyDoc.dokkaJavadocJar)
+ artifact(dairyDoc.dokkaHtmlJar)
pom {
description.set("Panels Battery Plugin")
@@ -80,12 +72,5 @@ afterEvaluate {
}
}
}
-
- repositories {
- maven {
- name = "localDevRepo"
- url = uri("file:///C:/Users/lazar/Documents/GitHub/ftcontrol-maven/releases")
- }
- }
}
}
diff --git a/library/Battery/web/bun.lock b/library/Battery/web/bun.lock
index b8db93ae..0d865e4a 100644
--- a/library/Battery/web/bun.lock
+++ b/library/Battery/web/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "panels-plugin",
diff --git a/library/CameraStream/build.gradle.kts b/library/CameraStream/build.gradle.kts
index e1f2e0f9..6769911d 100644
--- a/library/CameraStream/build.gradle.kts
+++ b/library/CameraStream/build.gradle.kts
@@ -1,60 +1,47 @@
-import org.gradle.kotlin.dsl.implementation
-
val pluginNamespace = "com.bylazar.camerastream"
val pluginVersion = "1.0.0"
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("maven-publish")
+ id("dev.frozenmilk.android-library") version "11.1.0-1.1.1"
id("com.bylazar.svelte-assets")
+ id("dev.frozenmilk.publish") version "0.0.5"
+ id("dev.frozenmilk.doc") version "0.0.5"
+ id("dev.frozenmilk.build-meta-data") version "0.0.2"
}
+android.namespace = pluginNamespace
+
svelteAssets {
- webAppPath = "web"
- buildDirPath = "dist"
- assetsPath = "web/plugins/$pluginNamespace"
+ assetsPath = assetPathForPlugin(pluginNamespace)
}
-android {
- namespace = pluginNamespace
-
- defaultConfig {
- compileSdk = 34
- minSdk = 24
- }
-
- buildTypes {
- getByName("release") {
- isMinifyEnabled = false
- }
- }
+dairyPublishing {
+ gitDir = file("..")
+}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- }
+version = "${dairyPublishing.version}+$pluginVersion"
- kotlinOptions {
- jvmTarget = "11"
- }
+meta {
+ packagePath = pluginNamespace
+ name = "CameraStream"
+ registerField("name", "String", "\"$pluginNamespace\"")
+ registerField("clean", "Boolean") { "${dairyPublishing.clean}" }
+ registerField("gitRef", "String") { "\"$version\"" }
+ registerField("snapshot", "Boolean") { "${dairyPublishing.snapshot}" }
+ registerField("version", "String") { "\"${dairyPublishing.version}\"" }
+}
- publishing {
- singleVariant("release") {}
+ftc {
+ kotlin()
+ sdk {
+ compileOnly(RobotCore)
+ compileOnly(FtcCommon)
}
}
dependencies {
- compileOnly("org.firstinspires.ftc:Inspection:11.0.0")
- compileOnly("org.firstinspires.ftc:Blocks:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotCore:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotServer:11.0.0")
- compileOnly("org.firstinspires.ftc:OnBotJava:11.0.0")
- compileOnly("org.firstinspires.ftc:Hardware:11.0.0")
- compileOnly("org.firstinspires.ftc:FtcCommon:11.0.0")
- compileOnly("org.firstinspires.ftc:Vision:11.0.0")
-
compileOnly(project(":Panels"))
+ // TODO: remove?
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1")
}
@@ -64,9 +51,11 @@ afterEvaluate {
create("release") {
from(components["release"])
- groupId = pluginNamespace.substringBeforeLast('.')
+ groupId = pluginNamespace.substringBeforeLast('.') + ".sloth"
artifactId = pluginNamespace.substringAfterLast('.')
- version = pluginVersion
+
+ artifact(dairyDoc.dokkaJavadocJar)
+ artifact(dairyDoc.dokkaHtmlJar)
pom {
description.set("Panels Camera Stream Plugin")
@@ -83,12 +72,5 @@ afterEvaluate {
}
}
}
-
- repositories {
- maven {
- name = "localDevRepo"
- url = uri("file:///C:/Users/lazar/Documents/GitHub/ftcontrol-maven/releases")
- }
- }
}
}
diff --git a/library/CameraStream/web/bun.lock b/library/CameraStream/web/bun.lock
index b8db93ae..0d865e4a 100644
--- a/library/CameraStream/web/bun.lock
+++ b/library/CameraStream/web/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "panels-plugin",
diff --git a/library/Capture/build.gradle.kts b/library/Capture/build.gradle.kts
index 221d9a28..b7f98856 100644
--- a/library/Capture/build.gradle.kts
+++ b/library/Capture/build.gradle.kts
@@ -2,56 +2,44 @@ val pluginNamespace = "com.bylazar.capture"
val pluginVersion = "1.0.3"
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("maven-publish")
+ id("dev.frozenmilk.android-library") version "11.1.0-1.1.1"
id("com.bylazar.svelte-assets")
+ id("dev.frozenmilk.publish") version "0.0.5"
+ id("dev.frozenmilk.doc") version "0.0.5"
+ id("dev.frozenmilk.build-meta-data") version "0.0.2"
}
+android.namespace = pluginNamespace
+
svelteAssets {
- webAppPath = "web"
- buildDirPath = "dist"
- assetsPath = "web/plugins/$pluginNamespace"
+ assetsPath = assetPathForPlugin(pluginNamespace)
}
-android {
- namespace = pluginNamespace
-
- defaultConfig {
- compileSdk = 34
- minSdk = 24
- }
-
- buildTypes {
- getByName("release") {
- isMinifyEnabled = false
- }
- }
+dairyPublishing {
+ gitDir = file("..")
+}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- }
+version = "${dairyPublishing.version}+$pluginVersion"
- kotlinOptions {
- jvmTarget = "11"
- }
+meta {
+ packagePath = pluginNamespace
+ name = "Capture"
+ registerField("name", "String", "\"$pluginNamespace\"")
+ registerField("clean", "Boolean") { "${dairyPublishing.clean}" }
+ registerField("gitRef", "String") { "\"${dairyPublishing.gitRef}\"" }
+ registerField("snapshot", "Boolean") { "${dairyPublishing.snapshot}" }
+ registerField("version", "String") { "\"$version\"" }
+}
- publishing {
- singleVariant("release") {}
+ftc {
+ kotlin()
+ sdk {
+ compileOnly(RobotCore)
+ compileOnly(FtcCommon)
}
}
dependencies {
- compileOnly("org.firstinspires.ftc:Inspection:11.0.0")
- compileOnly("org.firstinspires.ftc:Blocks:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotCore:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotServer:11.0.0")
- compileOnly("org.firstinspires.ftc:OnBotJava:11.0.0")
- compileOnly("org.firstinspires.ftc:Hardware:11.0.0")
- compileOnly("org.firstinspires.ftc:FtcCommon:11.0.0")
- compileOnly("org.firstinspires.ftc:Vision:11.0.0")
-
compileOnly(project(":Panels"))
}
@@ -61,9 +49,11 @@ afterEvaluate {
create("release") {
from(components["release"])
- groupId = pluginNamespace.substringBeforeLast('.')
+ groupId = pluginNamespace.substringBeforeLast('.') + ".sloth"
artifactId = pluginNamespace.substringAfterLast('.')
- version = pluginVersion
+
+ artifact(dairyDoc.dokkaJavadocJar)
+ artifact(dairyDoc.dokkaHtmlJar)
pom {
description.set("Panels Capture Plugin")
@@ -80,12 +70,5 @@ afterEvaluate {
}
}
}
-
- repositories {
- maven {
- name = "localDevRepo"
- url = uri("file:///C:/Users/lazar/Documents/GitHub/ftcontrol-maven/releases")
- }
- }
}
}
diff --git a/library/Capture/web/bun.lock b/library/Capture/web/bun.lock
index d9b44e64..56b2352a 100644
--- a/library/Capture/web/bun.lock
+++ b/library/Capture/web/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "panels-plugin",
diff --git a/library/Configurables/build.gradle.kts b/library/Configurables/build.gradle.kts
index b47b2f62..18f6aee7 100644
--- a/library/Configurables/build.gradle.kts
+++ b/library/Configurables/build.gradle.kts
@@ -2,56 +2,48 @@ val pluginNamespace = "com.bylazar.configurables"
val pluginVersion = "1.0.5"
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("maven-publish")
+ id("dev.frozenmilk.android-library") version "11.1.0-1.1.1"
id("com.bylazar.svelte-assets")
+ id("dev.frozenmilk.publish") version "0.0.5"
+ id("dev.frozenmilk.doc") version "0.0.5"
+ id("dev.frozenmilk.build-meta-data") version "0.0.2"
}
+android.namespace = pluginNamespace
+
svelteAssets {
- webAppPath = "web"
- buildDirPath = "dist"
- assetsPath = "web/plugins/$pluginNamespace"
+ assetsPath = assetPathForPlugin(pluginNamespace)
}
-android {
- namespace = pluginNamespace
+dairyPublishing {
+ gitDir = file("..")
+}
- defaultConfig {
- compileSdk = 34
- minSdk = 24
- }
+version = "${dairyPublishing.version}+$pluginVersion"
- buildTypes {
- getByName("release") {
- isMinifyEnabled = false
- }
- }
+meta {
+ packagePath = pluginNamespace
+ name = "Configurables"
+ registerField("name", "String", "\"$pluginNamespace\"")
+ registerField("clean", "Boolean") { "${dairyPublishing.clean}" }
+ registerField("gitRef", "String") { "\"${dairyPublishing.gitRef}\"" }
+ registerField("snapshot", "Boolean") { "${dairyPublishing.snapshot}" }
+ registerField("version", "String") { "\"${dairyPublishing.version}\"" }
+}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
+ftc {
+ kotlin()
+ sdk {
+ compileOnly(RobotCore)
+ compileOnly(FtcCommon)
+ compileOnly(RobotServer)
}
-
- kotlinOptions {
- jvmTarget = "11"
- }
-
- publishing {
- singleVariant("release") {}
+ dairy {
+ implementation(Sloth)
}
}
dependencies {
- compileOnly("org.firstinspires.ftc:Inspection:11.0.0")
- compileOnly("org.firstinspires.ftc:Blocks:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotCore:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotServer:11.0.0")
- compileOnly("org.firstinspires.ftc:OnBotJava:11.0.0")
- compileOnly("org.firstinspires.ftc:Hardware:11.0.0")
- compileOnly("org.firstinspires.ftc:FtcCommon:11.0.0")
- compileOnly("org.firstinspires.ftc:Vision:11.0.0")
-
compileOnly(project(":Panels"))
}
@@ -61,9 +53,11 @@ afterEvaluate {
create("release") {
from(components["release"])
- groupId = pluginNamespace.substringBeforeLast('.')
+ groupId = pluginNamespace.substringBeforeLast('.') + ".sloth"
artifactId = pluginNamespace.substringAfterLast('.')
- version = pluginVersion
+
+ artifact(dairyDoc.dokkaHtmlJar)
+ artifact(dairyDoc.dokkaJavadocJar)
pom {
description.set("Panels Configurables Plugin")
@@ -80,12 +74,5 @@ afterEvaluate {
}
}
}
-
- repositories {
- maven {
- name = "localDevRepo"
- url = uri("file:///C:/Users/lazar/Documents/GitHub/ftcontrol-maven/releases")
- }
- }
}
}
diff --git a/library/Configurables/src/main/java/com/bylazar/configurables/ConfigurablesPlugin.kt b/library/Configurables/src/main/java/com/bylazar/configurables/ConfigurablesPlugin.kt
index 27665e64..cfe8d059 100644
--- a/library/Configurables/src/main/java/com/bylazar/configurables/ConfigurablesPlugin.kt
+++ b/library/Configurables/src/main/java/com/bylazar/configurables/ConfigurablesPlugin.kt
@@ -1,40 +1,38 @@
package com.bylazar.configurables
-import android.R.attr.type
import android.content.Context
-import com.bylazar.configurables.GlobalConfigurables
+import com.bylazar.configurables.GlobalConfigurables.fieldsMap
import com.bylazar.configurables.GlobalConfigurables.jvmFields
+import com.bylazar.configurables.GlobalConfigurables.loadedFieldsMap
import com.bylazar.configurables.annotations.Configurable
import com.bylazar.configurables.annotations.IgnoreConfigurable
-import com.bylazar.configurables.variables.MyField
+import com.bylazar.configurables.annotations.Sorter
import com.bylazar.configurables.variables.generics.GenericField
import com.bylazar.panels.Panels
import com.bylazar.panels.json.SocketMessage
import com.bylazar.panels.plugins.BasePluginConfig
import com.bylazar.panels.plugins.Plugin
-import com.bylazar.panels.reflection.ClassFinder
import com.bylazar.panels.server.Socket
import com.qualcomm.ftccommon.FtcEventLoop
import com.qualcomm.robotcore.eventloop.opmode.OpMode
import com.qualcomm.robotcore.eventloop.opmode.OpModeManagerImpl
+import dev.frozenmilk.sinister.Scanner
+import dev.frozenmilk.sinister.loaders.RootClassLoader
+import dev.frozenmilk.sinister.targeting.WideSearch
import java.lang.reflect.Modifier
-import kotlin.jvm.java
-open class ConfigurablesPluginConfig : BasePluginConfig() {
-}
+open class ConfigurablesPluginConfig : BasePluginConfig() {}
-object Plugin : Plugin(ConfigurablesPluginConfig()) {
- var fieldsMap = mutableMapOf()
- var configurableClasses: List = listOf()
- var allFields: MutableList = mutableListOf()
+object Plugin : Plugin(ConfigurablesPluginConfig()), Scanner {
+ private val allFieldsMap: Map>
+ get() = jvmFields//
+ .flatMap { it.value.map(GenericField::toJsonType) }//
+ .groupBy { it.className }.toSortedMap()
- val allFieldsMap: Map>
- get() = allFields.groupBy { it.className }.toSortedMap()
-
- var initialAFieldsMap: Map> = mapOf()
+ private var initialFieldsMap: Map> = mapOf()
override fun onNewClient(client: Socket.ClientSocket) {
- sendClient(client, "initialConfigurables", initialAFieldsMap)
+ sendClient(client, "initialConfigurables", initialFieldsMap)
sendClient(client, "configurables", allFieldsMap)
}
@@ -48,110 +46,72 @@ object Plugin : Plugin(ConfigurablesPluginConfig()) {
emptyList()
}
- if(changes == null) return
+ if (changes == null) return
changes.forEach {
- val generalRef = GlobalConfigurables.fieldsMap[it.id] ?: return
+ val generalRef = fieldsMap[it.id] ?: return
log("Field id: ${it.id}, New value: ${it.newValueString}")
generalRef.setValue(it.newValueString)
it.newValueString = generalRef.getValue().toString()
-
- allFields = jvmFields.map { it.toJsonType }.toMutableList()
}
send("newConfigurables", changes)
}
}
- fun refreshClass(className: String) {
- allFields.removeAll { it.className == className }
-
- val fields: MutableList = mutableListOf()
-
- try {
- val clazz = Class.forName(className)
- log("Inspecting class $className")
- fields.addFieldsFromClass(clazz, className)
- try {
- val companionClazz = Class.forName("${className}\$Companion")
- fields.addFieldsFromClass(companionClazz, className)
- } catch (e: ClassNotFoundException) {
- // no companion found
+ fun refreshClass(cls: Class<*>) {
+ jvmFields.forEach { (loader, fields) ->
+ if(fields.removeIf { it.reference.declaringClass == cls }) {
+ scan(loader, cls)
+ send("configurables", allFieldsMap)
+ return
}
- } catch (e: Exception) {
- error("Error inspecting class ${className}: ${e.message}")
}
-
- val newFields = fields.map { it.toJsonType }.toMutableList()
-
- allFields.addAll(newFields)
-
- send("configurables", allFieldsMap)
}
override fun onRegister(
- panelsInstance: Panels,
- context: Context
+ panelsInstance: Panels, context: Context
) {
log("Initializing configurables")
- fieldsMap = mutableMapOf()
- configurableClasses = listOf()
-
- GlobalConfigurables.jvmFields = mutableListOf()
- GlobalConfigurables.fieldsMap = mutableMapOf()
-
- configurableClasses = ClassFinder.findClasses(
- { clazz ->
- val hasConfigurable =
- clazz.isAnnotationPresent(Configurable::class.java)
- val hasIgnoreConfigurable =
- clazz.isAnnotationPresent(IgnoreConfigurable::class.java)
- val shouldKeep =
- hasConfigurable && !hasIgnoreConfigurable
-
- shouldKeep
- }
- )
+ }
- log("Configurable classes: ${configurableClasses.map { it.className }}")
+ override fun onAttachEventLoop(eventLoop: FtcEventLoop) {
+ }
- val fields: MutableList = mutableListOf()
+ override fun onOpModeManager(o: OpModeManagerImpl) {
+ }
- configurableClasses.forEach {
- val className = it.className
+ override fun onOpModePreInit(opMode: OpMode) {
+ }
- try {
- val clazz = Class.forName(className)
- log("Inspecting class $className")
- fields.addFieldsFromClass(clazz, className)
- try {
- val companionClazz = Class.forName("${className}\$Companion")
- fields.addFieldsFromClass(companionClazz, className)
- } catch (e: ClassNotFoundException) {
- // no companion found
- }
- } catch (e: Exception) {
- error("Error inspecting class ${className}: ${e.message}")
- }
- }
+ override fun onOpModePreStart(opMode: OpMode) {
+ }
- log("Configurable fields: ${fields.map { it.name }}")
+ override fun onOpModePostStop(opMode: OpMode) {
+ }
- allFields = jvmFields.map { it.toJsonType }.filter { it.className != "class java.lang.ClassLoader" && it.className != "class sun.misc.Unsafe" }.toMutableList()
- initialAFieldsMap = allFieldsMap
+ override fun onEnablePanels() {
+ }
- send("initialConfigurables", initialAFieldsMap)
- send("configurables", allFieldsMap)
+ override fun onDisablePanels() {
}
- private fun MutableList.addFieldsFromClass(
- clazz: Class<*>,
- originalClassName: String
- ) {
- log("Sorting fields for class ${clazz.simpleName}")
- val fields = clazz.declaredFields.sortedBy { field ->
- val sort = field.getAnnotation(com.bylazar.configurables.annotations.Sorter::class.java)?.sort
+ //
+ // Scanner
+ //
+
+ override val loadAdjacencyRule = Scanner.INDEPENDENT
+ override val unloadAdjacencyRule = Scanner.INDEPENDENT
+ override val targets = WideSearch()
+
+ override fun scan(loader: ClassLoader, cls: Class<*>) {
+ if (!cls.isAnnotationPresent(Configurable::class.java)) return
+ if (cls.isAnnotationPresent(IgnoreConfigurable::class.java)) return
+
+ log("Sorting fields for class ${cls.simpleName}")
+ val fields = cls.declaredFields.sortedBy { field ->
+ val sort = field.getAnnotation(Sorter::class.java)?.sort
log("Field ${field.name} has sort value: $sort")
sort ?: Int.MAX_VALUE
}
@@ -162,16 +122,6 @@ object Plugin : Plugin(ConfigurablesPluginConfig()) {
val isStatic = Modifier.isStatic(field.modifiers)
val isIgnored = field.isAnnotationPresent(IgnoreConfigurable::class.java)
- val isPrivate = Modifier.isPrivate(field.modifiers)
- val isNull = try {
- if (field.get(null) == null) {
- println("PANELS: Field ${field.name} in $clazz is null")
- true
- } else false
- } catch (t: Throwable) {
- false
- }
-
val isJvmField = !isFinal && isStatic && !isIgnored
val fieldTypeName = field.type.canonicalName ?: ""
@@ -179,38 +129,30 @@ object Plugin : Plugin(ConfigurablesPluginConfig()) {
log("Found field of $fieldTypeName / $isJvmField")
if (isJvmField) {
- val displayClassName =
- if (clazz.name.endsWith("\$Companion")) originalClassName else clazz.name
- val genericField = GenericField(className = displayClassName, reference = field)
+ val displayClassName = cls.kotlin.simpleName ?: cls.name
+ val genericField = GenericField(classLoader = loader, className = displayClassName, reference = field)
log("Adding field $genericField / ${genericField.type} / ${genericField.value} / ${genericField.isNull}")
- add(genericField)
- GlobalConfigurables.jvmFields.add(genericField)
+ jvmFields.getOrPut(loader, ::mutableListOf).add(genericField)
}
} catch (t: Throwable) {
- error("Error inspecting field ${field.name} in $clazz: ${t.message}")
+ error("Error inspecting field ${field.name} in $cls: ${t.message}")
}
}
}
- override fun onAttachEventLoop(eventLoop: FtcEventLoop) {
- }
-
- override fun onOpModeManager(o: OpModeManagerImpl) {
- }
-
- override fun onOpModePreInit(opMode: OpMode) {
- }
-
- override fun onOpModePreStart(opMode: OpMode) {
- }
-
- override fun onOpModePostStop(opMode: OpMode) {
+ override fun afterScan(loader: ClassLoader) {
+ initialFieldsMap = allFieldsMap
+ send("initialConfigurables", initialFieldsMap)
+ send("configurables", allFieldsMap)
}
-
- override fun onEnablePanels() {
+ override fun beforeUnload(loader: ClassLoader) {
+ jvmFields.remove(loader)
+ loadedFieldsMap.remove(loader)?.forEach(fieldsMap::remove)
+ initialFieldsMap = allFieldsMap
+ send("initialConfigurables", initialFieldsMap)
+ send("configurables", allFieldsMap)
}
- override fun onDisablePanels() {
- }
+ override fun unload(loader: ClassLoader, cls: Class<*>) {}
}
\ No newline at end of file
diff --git a/library/Configurables/src/main/java/com/bylazar/configurables/GlobalConfigurables.kt b/library/Configurables/src/main/java/com/bylazar/configurables/GlobalConfigurables.kt
index 8f713961..2d97f5e5 100644
--- a/library/Configurables/src/main/java/com/bylazar/configurables/GlobalConfigurables.kt
+++ b/library/Configurables/src/main/java/com/bylazar/configurables/GlobalConfigurables.kt
@@ -4,7 +4,7 @@ import com.bylazar.configurables.variables.MyField
import com.bylazar.configurables.variables.generics.GenericField
object GlobalConfigurables {
- var jvmFields = mutableListOf()
-
+ var jvmFields = mutableMapOf>()
+ var loadedFieldsMap = mutableMapOf>()
var fieldsMap = mutableMapOf()
}
\ No newline at end of file
diff --git a/library/Configurables/src/main/java/com/bylazar/configurables/PanelsConfigurables.kt b/library/Configurables/src/main/java/com/bylazar/configurables/PanelsConfigurables.kt
index c5f8ae87..d9a67545 100644
--- a/library/Configurables/src/main/java/com/bylazar/configurables/PanelsConfigurables.kt
+++ b/library/Configurables/src/main/java/com/bylazar/configurables/PanelsConfigurables.kt
@@ -1,8 +1,16 @@
package com.bylazar.configurables
+import kotlin.reflect.KClass
+
object PanelsConfigurables {
- fun refreshClass(cls: Any) {
- val name = cls::class.qualifiedName ?: return
- Plugin.refreshClass(name)
- }
+ @Deprecated(
+ "this function is misleading, instead, use the variants that take a class",
+ replaceWith = ReplaceWith("refreshClass(cls::class)")
+ )
+ @JvmStatic
+ fun refreshClass(cls: Any) = refreshClass(cls.javaClass)
+ @JvmStatic
+ fun refreshClass(cls: KClass<*>) = Plugin.refreshClass(cls.java)
+ @JvmStatic
+ fun refreshClass(cls: Class<*>) = Plugin.refreshClass(cls)
}
\ No newline at end of file
diff --git a/library/Configurables/src/main/java/com/bylazar/configurables/variables/MyField.kt b/library/Configurables/src/main/java/com/bylazar/configurables/variables/MyField.kt
index ebfe43d3..d1362538 100644
--- a/library/Configurables/src/main/java/com/bylazar/configurables/variables/MyField.kt
+++ b/library/Configurables/src/main/java/com/bylazar/configurables/variables/MyField.kt
@@ -10,9 +10,10 @@ import java.util.Locale
import java.util.UUID
import kotlin.text.*
-class MyField(
+class MyField constructor(
val name: String,
val type: Class<*>,
+ val classLoader: ClassLoader,
var isAccessible: Boolean,
var get: (instance: Any?) -> Any?,
var set: (instance: Any?, newValue: Any?) -> Unit,
@@ -32,6 +33,7 @@ class MyField(
init {
if (ref != null) ref.isAccessible = true
GlobalConfigurables.fieldsMap[id] = this
+ GlobalConfigurables.loadedFieldsMap.getOrPut(classLoader, ::mutableListOf).add(id)
}
fun getValue(recursionDepth: Int = 0): Any? {
@@ -79,10 +81,11 @@ class MyField(
}
}
-fun convertToMyField(field: Field): MyField {
+fun convertToMyField(classLoader: ClassLoader, field: Field): MyField {
return MyField(
name = field.name,
type = field.type,
+ classLoader = classLoader,
isAccessible = field.isAccessible,
get = field::get,
set = field::set,
@@ -95,6 +98,7 @@ fun convertToMyField(field: MyField, parentField: MyField?, className: String):
return MyField(
name = field.name,
type = field.type,
+ classLoader = field.classLoader,
isAccessible = field.isAccessible,
get = field.get,
set = field.set,
diff --git a/library/Configurables/src/main/java/com/bylazar/configurables/variables/generics/GenericField.kt b/library/Configurables/src/main/java/com/bylazar/configurables/variables/generics/GenericField.kt
index d5dabf42..05d136b8 100644
--- a/library/Configurables/src/main/java/com/bylazar/configurables/variables/generics/GenericField.kt
+++ b/library/Configurables/src/main/java/com/bylazar/configurables/variables/generics/GenericField.kt
@@ -10,12 +10,13 @@ import com.bylazar.configurables.variables.processValue
import java.lang.reflect.Field
class GenericField(
+ classLoader: ClassLoader,
var className: String,
var reference: Field,
) {
- val type = getType(reference.type, convertToMyField(reference), null)
- val value: GenericVariable = processValue(0, className, type, convertToMyField(reference), null)
+ val type = getType(reference.type, convertToMyField(classLoader, reference), null)
+ val value: GenericVariable = processValue(0, className, classLoader, type, convertToMyField(classLoader, reference), null)
val isNull: Boolean
get() = toJsonType.type == BaseTypes.JSON_ERROR
diff --git a/library/Configurables/src/main/java/com/bylazar/configurables/variables/processValue.kt b/library/Configurables/src/main/java/com/bylazar/configurables/variables/processValue.kt
index f30c3370..12fd31e3 100644
--- a/library/Configurables/src/main/java/com/bylazar/configurables/variables/processValue.kt
+++ b/library/Configurables/src/main/java/com/bylazar/configurables/variables/processValue.kt
@@ -23,6 +23,7 @@ class RecursionDetectedException(val fieldName: String) : RuntimeException()
fun processValue(
recursionDepth: Int,
className: String,
+ classLoader: ClassLoader,
type: BaseTypes,
reference: MyField,
parentReference: MyField?,
@@ -58,7 +59,8 @@ fun processValue(
if (type == BaseTypes.CUSTOM) {
reference.isAccessible = true
val customValues = reference.type.declaredFields.sortedBy { field ->
- field.getAnnotation(com.bylazar.configurables.annotations.Sorter::class.java)?.sort ?: Int.MAX_VALUE
+ field.getAnnotation(com.bylazar.configurables.annotations.Sorter::class.java)?.sort
+ ?: Int.MAX_VALUE
}.mapNotNull { field ->
try {
field.isAccessible = true
@@ -75,13 +77,15 @@ fun processValue(
// return@mapNotNull null
// }
if (field.type == reference.type) {
- val newField = GenericField(reference.type.toString(), field)
- val alreadyExists = GlobalConfigurables.jvmFields.any {
- it.className == newField.className && it.reference.name == newField.reference.name
+ val newField = GenericField(classLoader, reference.type.toString(), field)
+ val alreadyExists = GlobalConfigurables.jvmFields.any { (_, fields) ->
+ fields.any {
+ it.className == newField.className && it.reference.name == newField.reference.name
+ }
}
if (!alreadyExists) {
- GlobalConfigurables.jvmFields.add(newField)
+ GlobalConfigurables.jvmFields.getOrPut(classLoader, ::mutableListOf).add(newField)
ConfigurablesLogger.log("Moved field to global configurable: ${reference.name} ${reference.type} ${field.name}")
} else {
ConfigurablesLogger.log("Skipped duplicate configurable: ${reference.name} ${reference.type} ${field.name}")
@@ -90,11 +94,12 @@ fun processValue(
return@mapNotNull null
}
- val customNewField = convertToMyField(field)
+ val customNewField = convertToMyField(classLoader, field)
processValue(
recursionDepth + 1,
className,
+ classLoader,
getType(field.type, customNewField, reference),
customNewField,
currentManager,
@@ -134,6 +139,7 @@ fun processValue(
val currentElementReference = MyField(
name = i.toString(),
type = cType,
+ classLoader = classLoader,
isAccessible = true,
get = { instance ->
Array.get(instance, i)
@@ -147,6 +153,7 @@ fun processValue(
processValue(
recursionDepth + 1,
className,
+ classLoader,
itemType,
currentElementReference,
currentManager,
@@ -186,6 +193,7 @@ fun processValue(
val currentElementReference = MyField(
name = index.toString(),
type = cType,
+ classLoader = classLoader,
isAccessible = true,
get = { instance ->
listInstance.getOrNull(index)
@@ -203,6 +211,7 @@ fun processValue(
processValue(
recursionDepth + 1,
className,
+ classLoader,
itemType,
currentElementReference,
currentManager,
@@ -228,6 +237,7 @@ fun processValue(
val currentElementReference = MyField(
name = key.toString(),
type = mapInstance[key]?.javaClass ?: Any::class.java,
+ classLoader = classLoader,
isAccessible = true,
get = { instance ->
mapInstance[key]
@@ -241,6 +251,7 @@ fun processValue(
processValue(
recursionDepth + 1,
className,
+ classLoader,
itemType,
currentElementReference,
currentManager,
diff --git a/library/Configurables/web/bun.lock b/library/Configurables/web/bun.lock
index b8db93ae..0d865e4a 100644
--- a/library/Configurables/web/bun.lock
+++ b/library/Configurables/web/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "panels-plugin",
diff --git a/library/Docs/build.gradle.kts b/library/Docs/build.gradle.kts
index 08064e3e..89c69dc2 100644
--- a/library/Docs/build.gradle.kts
+++ b/library/Docs/build.gradle.kts
@@ -2,56 +2,45 @@ val pluginNamespace = "com.bylazar.docs"
val pluginVersion = "1.0.5"
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("maven-publish")
+ id("dev.frozenmilk.android-library") version "11.1.0-1.1.1"
id("com.bylazar.svelte-assets")
+ id("dev.frozenmilk.publish") version "0.0.5"
+ id("dev.frozenmilk.doc") version "0.0.5"
+ id("dev.frozenmilk.build-meta-data") version "0.0.2"
}
+android.namespace = pluginNamespace
+
svelteAssets {
- webAppPath = "web"
- buildDirPath = "dist"
- assetsPath = "web/plugins/$pluginNamespace"
+ assetsPath = assetPathForPlugin(pluginNamespace)
}
-android {
- namespace = pluginNamespace
-
- defaultConfig {
- compileSdk = 34
- minSdk = 24
- }
-
- buildTypes {
- getByName("release") {
- isMinifyEnabled = false
- }
- }
+dairyPublishing {
+ gitDir = file("..")
+}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- }
+version = "${dairyPublishing.version}+$pluginVersion"
- kotlinOptions {
- jvmTarget = "11"
- }
+meta {
+ packagePath = pluginNamespace
+ name = "Docs"
+ registerField("name", "String", "\"$pluginNamespace\"")
+ registerField("clean", "Boolean") { "${dairyPublishing.clean}" }
+ registerField("gitRef", "String") { "\"${dairyPublishing.gitRef}\"" }
+ registerField("snapshot", "Boolean") { "${dairyPublishing.snapshot}" }
+ registerField("version", "String") { "\"$version\"" }
+}
- publishing {
- singleVariant("release") {}
+ftc {
+ kotlin()
+ sdk {
+ compileOnly(RobotCore)
+ compileOnly(FtcCommon)
+ compileOnly(RobotServer)
}
}
dependencies {
- compileOnly("org.firstinspires.ftc:Inspection:11.0.0")
- compileOnly("org.firstinspires.ftc:Blocks:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotCore:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotServer:11.0.0")
- compileOnly("org.firstinspires.ftc:OnBotJava:11.0.0")
- compileOnly("org.firstinspires.ftc:Hardware:11.0.0")
- compileOnly("org.firstinspires.ftc:FtcCommon:11.0.0")
- compileOnly("org.firstinspires.ftc:Vision:11.0.0")
-
compileOnly(project(":Panels"))
}
@@ -61,9 +50,11 @@ afterEvaluate {
create("release") {
from(components["release"])
- groupId = pluginNamespace.substringBeforeLast('.')
+ groupId = pluginNamespace.substringBeforeLast('.') + ".sloth"
artifactId = pluginNamespace.substringAfterLast('.')
- version = pluginVersion
+
+ artifact(dairyDoc.dokkaJavadocJar)
+ artifact(dairyDoc.dokkaHtmlJar)
pom {
description.set("Panels Docs Plugin")
@@ -80,12 +71,5 @@ afterEvaluate {
}
}
}
-
- repositories {
- maven {
- name = "localDevRepo"
- url = uri("file:///C:/Users/lazar/Documents/GitHub/ftcontrol-maven/releases")
- }
- }
}
}
diff --git a/library/Docs/web/bun.lock b/library/Docs/web/bun.lock
index b8db93ae..0d865e4a 100644
--- a/library/Docs/web/bun.lock
+++ b/library/Docs/web/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "panels-plugin",
diff --git a/library/ExamplePlugin/build.gradle.kts b/library/ExamplePlugin/build.gradle.kts
index ccc2032d..a920a958 100644
--- a/library/ExamplePlugin/build.gradle.kts
+++ b/library/ExamplePlugin/build.gradle.kts
@@ -2,56 +2,45 @@ val pluginNamespace = "com.bylazar.exampleplugin"
val pluginVersion = "0.0.14"
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("maven-publish")
+ id("dev.frozenmilk.android-library") version "11.1.0-1.1.1"
id("com.bylazar.svelte-assets")
+ id("dev.frozenmilk.publish") version "0.0.5"
+ id("dev.frozenmilk.doc") version "0.0.5"
+ id("dev.frozenmilk.build-meta-data") version "0.0.2"
}
+android.namespace = pluginNamespace
+
svelteAssets {
- webAppPath = "web"
- buildDirPath = "dist"
- assetsPath = "web/plugins/$pluginNamespace"
+ assetsPath = assetPathForPlugin(pluginNamespace)
}
-android {
- namespace = pluginNamespace
-
- defaultConfig {
- compileSdk = 34
- minSdk = 24
- }
-
- buildTypes {
- getByName("release") {
- isMinifyEnabled = false
- }
- }
+dairyPublishing {
+ gitDir = file("..")
+}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- }
+version = "${dairyPublishing.version}+$pluginVersion"
- kotlinOptions {
- jvmTarget = "11"
- }
+meta {
+ packagePath = pluginNamespace
+ name = "Example"
+ registerField("name", "String", "\"$pluginNamespace\"")
+ registerField("clean", "Boolean") { "${dairyPublishing.clean}" }
+ registerField("gitRef", "String") { "\"${dairyPublishing.gitRef}\"" }
+ registerField("snapshot", "Boolean") { "${dairyPublishing.snapshot}" }
+ registerField("version", "String") { "\"$version\"" }
+}
- publishing {
- singleVariant("release") {}
+ftc {
+ kotlin()
+ sdk {
+ compileOnly(RobotCore)
+ compileOnly(FtcCommon)
+ compileOnly(RobotServer)
}
}
dependencies {
- compileOnly("org.firstinspires.ftc:Inspection:11.0.0")
- compileOnly("org.firstinspires.ftc:Blocks:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotCore:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotServer:11.0.0")
- compileOnly("org.firstinspires.ftc:OnBotJava:11.0.0")
- compileOnly("org.firstinspires.ftc:Hardware:11.0.0")
- compileOnly("org.firstinspires.ftc:FtcCommon:11.0.0")
- compileOnly("org.firstinspires.ftc:Vision:11.0.0")
-
compileOnly(project(":Panels"))
}
@@ -61,9 +50,11 @@ afterEvaluate {
create("release") {
from(components["release"])
- groupId = pluginNamespace.substringBeforeLast('.')
+ groupId = pluginNamespace.substringBeforeLast('.') + ".sloth"
artifactId = pluginNamespace.substringAfterLast('.')
- version = pluginVersion
+
+ artifact(dairyDoc.dokkaJavadocJar)
+ artifact(dairyDoc.dokkaHtmlJar)
pom {
description.set("Panels Example Plugin")
@@ -80,12 +71,5 @@ afterEvaluate {
}
}
}
-
- repositories {
- maven {
- name = "localDevRepo"
- url = uri("file:///C:/Users/lazar/Documents/GitHub/ftcontrol-maven/releases")
- }
- }
}
}
diff --git a/library/ExamplePlugin/web/bun.lock b/library/ExamplePlugin/web/bun.lock
index d9b44e64..56b2352a 100644
--- a/library/ExamplePlugin/web/bun.lock
+++ b/library/ExamplePlugin/web/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "panels-plugin",
diff --git a/library/Field/build.gradle.kts b/library/Field/build.gradle.kts
index dca32acb..225e8fe8 100644
--- a/library/Field/build.gradle.kts
+++ b/library/Field/build.gradle.kts
@@ -2,56 +2,45 @@ val pluginNamespace = "com.bylazar.field"
val pluginVersion = "1.0.6"
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("maven-publish")
+ id("dev.frozenmilk.android-library") version "11.1.0-1.1.1"
id("com.bylazar.svelte-assets")
+ id("dev.frozenmilk.publish") version "0.0.5"
+ id("dev.frozenmilk.doc") version "0.0.5"
+ id("dev.frozenmilk.build-meta-data") version "0.0.2"
}
+android.namespace = pluginNamespace
+
svelteAssets {
- webAppPath = "web"
- buildDirPath = "dist"
- assetsPath = "web/plugins/$pluginNamespace"
+ assetsPath = assetPathForPlugin(pluginNamespace)
}
-android {
- namespace = pluginNamespace
-
- defaultConfig {
- compileSdk = 34
- minSdk = 24
- }
-
- buildTypes {
- getByName("release") {
- isMinifyEnabled = false
- }
- }
+dairyPublishing {
+ gitDir = file("..")
+}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- }
+version = "${dairyPublishing.version}+$pluginVersion"
- kotlinOptions {
- jvmTarget = "11"
- }
+meta {
+ packagePath = pluginNamespace
+ name = "Field"
+ registerField("name", "String", "\"$pluginNamespace\"")
+ registerField("clean", "Boolean") { "${dairyPublishing.clean}" }
+ registerField("gitRef", "String") { "\"${dairyPublishing.gitRef}\"" }
+ registerField("snapshot", "Boolean") { "${dairyPublishing.snapshot}" }
+ registerField("version", "String") { "\"$version\"" }
+}
- publishing {
- singleVariant("release") {}
+ftc {
+ kotlin()
+ sdk {
+ compileOnly(RobotCore)
+ compileOnly(FtcCommon)
+ compileOnly(RobotServer)
}
}
dependencies {
- compileOnly("org.firstinspires.ftc:Inspection:11.0.0")
- compileOnly("org.firstinspires.ftc:Blocks:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotCore:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotServer:11.0.0")
- compileOnly("org.firstinspires.ftc:OnBotJava:11.0.0")
- compileOnly("org.firstinspires.ftc:Hardware:11.0.0")
- compileOnly("org.firstinspires.ftc:FtcCommon:11.0.0")
- compileOnly("org.firstinspires.ftc:Vision:11.0.0")
-
compileOnly(project(":Panels"))
}
@@ -61,9 +50,11 @@ afterEvaluate {
create("release") {
from(components["release"])
- groupId = pluginNamespace.substringBeforeLast('.')
+ groupId = pluginNamespace.substringBeforeLast('.') + ".sloth"
artifactId = pluginNamespace.substringAfterLast('.')
- version = pluginVersion
+
+ artifact(dairyDoc.dokkaJavadocJar)
+ artifact(dairyDoc.dokkaHtmlJar)
pom {
description.set("Panels Field Plugin")
@@ -80,12 +71,5 @@ afterEvaluate {
}
}
}
-
- repositories {
- maven {
- name = "localDevRepo"
- url = uri("file:///C:/Users/lazar/Documents/GitHub/ftcontrol-maven/releases")
- }
- }
}
}
diff --git a/library/Field/web/bun.lock b/library/Field/web/bun.lock
index b8db93ae..0d865e4a 100644
--- a/library/Field/web/bun.lock
+++ b/library/Field/web/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "panels-plugin",
diff --git a/library/FtcRobotController/build.gradle b/library/FtcRobotController/build.gradle
deleted file mode 100644
index 86fdd50f..00000000
--- a/library/FtcRobotController/build.gradle
+++ /dev/null
@@ -1,25 +0,0 @@
-import java.text.SimpleDateFormat
-
-apply plugin: 'com.android.library'
-
-apply from: '../build.dependencies.gradle'
-android {
-
- defaultConfig {
- minSdkVersion 24
- //noinspection ExpiredTargetSdkVersion
- targetSdkVersion 28
- compileSdk = 34
- buildConfigField "String", "APP_BUILD_TIME", '"' + (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.ROOT).format(new Date())) + '"'
- }
-
- buildFeatures {
- buildConfig = true
- }
-
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
- namespace = 'com.qualcomm.ftcrobotcontroller'
-}
diff --git a/library/FtcRobotController/src/main/AndroidManifest.xml b/library/FtcRobotController/src/main/AndroidManifest.xml
deleted file mode 100644
index 24038bfa..00000000
--- a/library/FtcRobotController/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/BasicOmniOpMode_Linear.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/BasicOmniOpMode_Linear.java
deleted file mode 100644
index 1d14dfb7..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/BasicOmniOpMode_Linear.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/* Copyright (c) 2021 FIRST. 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 com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.util.ElapsedTime;
-
-/*
- * This file contains an example of a Linear "OpMode".
- * An OpMode is a 'program' that runs in either the autonomous or the teleop period of an FTC match.
- * The names of OpModes appear on the menu of the FTC Driver Station.
- * When a selection is made from the menu, the corresponding OpMode is executed.
- *
- * This particular OpMode illustrates driving a 4-motor Omni-Directional (or Holonomic) robot.
- * This code will work with either a Mecanum-Drive or an X-Drive train.
- * Both of these drives are illustrated at https://gm0.org/en/latest/docs/robot-design/drivetrains/holonomic.html
- * Note that a Mecanum drive must display an X roller-pattern when viewed from above.
- *
- * Also note that it is critical to set the correct rotation direction for each motor. See details below.
- *
- * Holonomic drives provide the ability for the robot to move in three axes (directions) simultaneously.
- * Each motion axis is controlled by one Joystick axis.
- *
- * 1) Axial: Driving forward and backward Left-joystick Forward/Backward
- * 2) Lateral: Strafing right and left Left-joystick Right and Left
- * 3) Yaw: Rotating Clockwise and counter clockwise Right-joystick Right and Left
- *
- * This code is written assuming that the right-side motors need to be reversed for the robot to drive forward.
- * When you first test your robot, if it moves backward when you push the left stick forward, then you must flip
- * the direction of all 4 motors (see code below).
- *
- * 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="Basic: Omni Linear OpMode", group="Linear OpMode")
-@Disabled
-public class BasicOmniOpMode_Linear extends LinearOpMode {
-
- // Declare OpMode members for each of the 4 motors.
- private ElapsedTime runtime = new ElapsedTime();
- private DcMotor leftFrontDrive = null;
- private DcMotor leftBackDrive = null;
- private DcMotor rightFrontDrive = null;
- private DcMotor rightBackDrive = null;
-
- @Override
- public void runOpMode() {
-
- // Initialize the hardware variables. Note that the strings used here must correspond
- // to the names assigned during the robot configuration step on the DS or RC devices.
- leftFrontDrive = hardwareMap.get(DcMotor.class, "left_front_drive");
- leftBackDrive = hardwareMap.get(DcMotor.class, "left_back_drive");
- rightFrontDrive = hardwareMap.get(DcMotor.class, "right_front_drive");
- rightBackDrive = hardwareMap.get(DcMotor.class, "right_back_drive");
-
- // ########################################################################################
- // !!! IMPORTANT Drive Information. Test your motor directions. !!!!!
- // ########################################################################################
- // Most robots need the motors on one side to be reversed to drive forward.
- // The motor reversals shown here are for a "direct drive" robot (the wheels turn the same direction as the motor shaft)
- // If your robot has additional gear reductions or uses a right-angled drive, it's important to ensure
- // that your motors are turning in the correct direction. So, start out with the reversals here, BUT
- // when you first test your robot, push the left joystick forward and observe the direction the wheels turn.
- // Reverse the direction (flip FORWARD <-> REVERSE ) of any wheel that runs backward
- // Keep testing until ALL the wheels move the robot forward when you push the left joystick forward.
- leftFrontDrive.setDirection(DcMotor.Direction.REVERSE);
- leftBackDrive.setDirection(DcMotor.Direction.REVERSE);
- rightFrontDrive.setDirection(DcMotor.Direction.FORWARD);
- rightBackDrive.setDirection(DcMotor.Direction.FORWARD);
-
- // Wait for the game to start (driver presses START)
- telemetry.addData("Status", "Initialized");
- telemetry.update();
-
- waitForStart();
- runtime.reset();
-
- // run until the end of the match (driver presses STOP)
- while (opModeIsActive()) {
- double max;
-
- // POV Mode uses left joystick to go forward & strafe, and right joystick to rotate.
- double axial = -gamepad1.left_stick_y; // Note: pushing stick forward gives negative value
- double lateral = gamepad1.left_stick_x;
- double yaw = gamepad1.right_stick_x;
-
- // Combine the joystick requests for each axis-motion to determine each wheel's power.
- // Set up a variable for each drive wheel to save the power level for telemetry.
- double leftFrontPower = axial + lateral + yaw;
- double rightFrontPower = axial - lateral - yaw;
- double leftBackPower = axial - lateral + yaw;
- double rightBackPower = axial + lateral - yaw;
-
- // Normalize the values so no wheel power exceeds 100%
- // This ensures that the robot maintains the desired motion.
- max = Math.max(Math.abs(leftFrontPower), Math.abs(rightFrontPower));
- max = Math.max(max, Math.abs(leftBackPower));
- max = Math.max(max, Math.abs(rightBackPower));
-
- if (max > 1.0) {
- leftFrontPower /= max;
- rightFrontPower /= max;
- leftBackPower /= max;
- rightBackPower /= max;
- }
-
- // This is test code:
- //
- // Uncomment the following code to test your motor directions.
- // Each button should make the corresponding motor run FORWARD.
- // 1) First get all the motors to take to correct positions on the robot
- // by adjusting your Robot Configuration if necessary.
- // 2) Then make sure they run in the correct direction by modifying the
- // the setDirection() calls above.
- // Once the correct motors move in the correct direction re-comment this code.
-
- /*
- leftFrontPower = gamepad1.x ? 1.0 : 0.0; // X gamepad
- leftBackPower = gamepad1.a ? 1.0 : 0.0; // A gamepad
- rightFrontPower = gamepad1.y ? 1.0 : 0.0; // Y gamepad
- rightBackPower = gamepad1.b ? 1.0 : 0.0; // B gamepad
- */
-
- // Send calculated power to wheels
- leftFrontDrive.setPower(leftFrontPower);
- rightFrontDrive.setPower(rightFrontPower);
- leftBackDrive.setPower(leftBackPower);
- rightBackDrive.setPower(rightBackPower);
-
- // Show the elapsed game time and wheel power.
- telemetry.addData("Status", "Run Time: " + runtime.toString());
- telemetry.addData("Front left/Right", "%4.2f, %4.2f", leftFrontPower, rightFrontPower);
- telemetry.addData("Back left/Right", "%4.2f, %4.2f", leftBackPower, rightBackPower);
- telemetry.update();
- }
- }}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/BasicOpMode_Iterative.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/BasicOpMode_Iterative.java
deleted file mode 100644
index 6504e58a..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/BasicOpMode_Iterative.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.OpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.util.ElapsedTime;
-import com.qualcomm.robotcore.util.Range;
-
-/*
- * This file contains an example of an iterative (Non-Linear) "OpMode".
- * An OpMode is a 'program' that runs in either the autonomous or the teleop period of an FTC match.
- * The names of OpModes appear on the menu of the FTC Driver Station.
- * When a selection is made from the menu, the corresponding OpMode
- * class is instantiated on the Robot Controller and executed.
- *
- * This particular OpMode just executes a basic Tank Drive Teleop for a two wheeled robot
- * It includes all the skeletal structure that all iterative OpModes contain.
- *
- * 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="Basic: Iterative OpMode", group="Iterative OpMode")
-@Disabled
-public class BasicOpMode_Iterative extends OpMode
-{
- // Declare OpMode members.
- private ElapsedTime runtime = new ElapsedTime();
- private DcMotor leftDrive = null;
- private DcMotor rightDrive = null;
-
- /*
- * Code to run ONCE when the driver hits INIT
- */
- @Override
- public void init() {
- telemetry.addData("Status", "Initialized");
-
- // Initialize the hardware variables. Note that the strings used here as parameters
- // to 'get' must correspond to the names assigned during the robot configuration
- // step (using the FTC Robot Controller app on the phone).
- leftDrive = hardwareMap.get(DcMotor.class, "left_drive");
- rightDrive = hardwareMap.get(DcMotor.class, "right_drive");
-
- // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
- // Pushing the left stick forward MUST make robot go forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Gear Reduction or 90 Deg drives may require direction flips
- leftDrive.setDirection(DcMotor.Direction.REVERSE);
- rightDrive.setDirection(DcMotor.Direction.FORWARD);
-
- // Tell the driver that initialization is complete.
- telemetry.addData("Status", "Initialized");
- }
-
- /*
- * Code to run REPEATEDLY after the driver hits INIT, but before they hit START
- */
- @Override
- public void init_loop() {
- }
-
- /*
- * Code to run ONCE when the driver hits START
- */
- @Override
- public void start() {
- runtime.reset();
- }
-
- /*
- * Code to run REPEATEDLY after the driver hits START but before they hit STOP
- */
- @Override
- public void loop() {
- // Setup a variable for each drive wheel to save power level for telemetry
- double leftPower;
- double rightPower;
-
- // Choose to drive using either Tank Mode, or POV Mode
- // Comment out the method that's not used. The default below is POV.
-
- // POV Mode uses left stick to go forward, and right stick to turn.
- // - This uses basic math to combine motions and is easier to drive straight.
- double drive = -gamepad1.left_stick_y;
- double turn = gamepad1.right_stick_x;
- leftPower = Range.clip(drive + turn, -1.0, 1.0) ;
- rightPower = Range.clip(drive - turn, -1.0, 1.0) ;
-
- // Tank Mode uses one stick to control each wheel.
- // - This requires no math, but it is hard to drive forward slowly and keep straight.
- // leftPower = -gamepad1.left_stick_y ;
- // rightPower = -gamepad1.right_stick_y ;
-
- // Send calculated power to wheels
- leftDrive.setPower(leftPower);
- rightDrive.setPower(rightPower);
-
- // Show the elapsed game time and wheel power.
- telemetry.addData("Status", "Run Time: " + runtime.toString());
- telemetry.addData("Motors", "left (%.2f), right (%.2f)", leftPower, rightPower);
- }
-
- /*
- * Code to run ONCE after the driver hits STOP
- */
- @Override
- public void stop() {
- }
-
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/BasicOpMode_Linear.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/BasicOpMode_Linear.java
deleted file mode 100644
index ab0bb254..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/BasicOpMode_Linear.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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 com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.util.ElapsedTime;
-import com.qualcomm.robotcore.util.Range;
-
-
-/*
- * This file contains an minimal example of a Linear "OpMode". An OpMode is a 'program' that runs in either
- * the autonomous or the teleop period of an FTC match. The names of OpModes appear on the menu
- * of the FTC Driver Station. When a selection is made from the menu, the corresponding OpMode
- * class is instantiated on the Robot Controller and executed.
- *
- * This particular OpMode just executes a basic Tank Drive Teleop for a two wheeled robot
- * It includes all the skeletal structure that all linear OpModes contain.
- *
- * 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="Basic: Linear OpMode", group="Linear OpMode")
-@Disabled
-public class BasicOpMode_Linear extends LinearOpMode {
-
- // Declare OpMode members.
- private ElapsedTime runtime = new ElapsedTime();
- private DcMotor leftDrive = null;
- private DcMotor rightDrive = null;
-
- @Override
- public void runOpMode() {
- telemetry.addData("Status", "Initialized");
- telemetry.update();
-
- // Initialize the hardware variables. Note that the strings used here as parameters
- // to 'get' must correspond to the names assigned during the robot configuration
- // step (using the FTC Robot Controller app on the phone).
- leftDrive = hardwareMap.get(DcMotor.class, "left_drive");
- rightDrive = hardwareMap.get(DcMotor.class, "right_drive");
-
- // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
- // Pushing the left stick forward MUST make robot go forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Gear Reduction or 90 Deg drives may require direction flips
- leftDrive.setDirection(DcMotor.Direction.REVERSE);
- rightDrive.setDirection(DcMotor.Direction.FORWARD);
-
- // Wait for the game to start (driver presses START)
- waitForStart();
- runtime.reset();
-
- // run until the end of the match (driver presses STOP)
- while (opModeIsActive()) {
-
- // Setup a variable for each drive wheel to save power level for telemetry
- double leftPower;
- double rightPower;
-
- // Choose to drive using either Tank Mode, or POV Mode
- // Comment out the method that's not used. The default below is POV.
-
- // POV Mode uses left stick to go forward, and right stick to turn.
- // - This uses basic math to combine motions and is easier to drive straight.
- double drive = -gamepad1.left_stick_y;
- double turn = gamepad1.right_stick_x;
- leftPower = Range.clip(drive + turn, -1.0, 1.0) ;
- rightPower = Range.clip(drive - turn, -1.0, 1.0) ;
-
- // Tank Mode uses one stick to control each wheel.
- // - This requires no math, but it is hard to drive forward slowly and keep straight.
- // leftPower = -gamepad1.left_stick_y ;
- // rightPower = -gamepad1.right_stick_y ;
-
- // Send calculated power to wheels
- leftDrive.setPower(leftPower);
- rightDrive.setPower(rightPower);
-
- // Show the elapsed game time and wheel power.
- telemetry.addData("Status", "Run Time: " + runtime.toString());
- telemetry.addData("Motors", "left (%.2f), right (%.2f)", leftPower, rightPower);
- telemetry.update();
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTag.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTag.java
deleted file mode 100644
index 8ec77dd8..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTag.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/* Copyright (c) 2023 FIRST. 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 android.util.Size;
-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.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 recognition and pose estimation,
- * including Java Builder structures for specifying Vision parameters.
- *
- * 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 have their position and orientation information displayed. 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 tag, relative to the camera.
- * This information is provided in the "ftcPose" member of the returned "detection", and is explained in the ftc-docs page linked below.
- * https://ftc-docs.firstinspires.org/apriltag-detection-values
- *
- * To experiment with using AprilTags to navigate, try out these two driving samples:
- * RobotAutoDriveToAprilTagOmni and RobotAutoDriveToAprilTagTank
- *
- * There are many "default" VisionPortal and AprilTag configuration parameters that may be overridden if desired.
- * These default parameters are shown as comments in the code below.
- *
- * 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", group = "Concept")
-@Disabled
-public class ConceptAprilTag extends LinearOpMode {
-
- private static final boolean USE_WEBCAM = true; // true for webcam, false for phone camera
-
- /**
- * 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();
-
- if (opModeIsActive()) {
- 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)
-
- // == 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 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.ftcPose.x, detection.ftcPose.y, detection.ftcPose.z));
- telemetry.addLine(String.format("PRY %6.1f %6.1f %6.1f (deg)", detection.ftcPose.pitch, detection.ftcPose.roll, detection.ftcPose.yaw));
- telemetry.addLine(String.format("RBE %6.1f %6.1f %6.1f (inch, deg, deg)", detection.ftcPose.range, detection.ftcPose.bearing, detection.ftcPose.elevation));
- } 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)");
- telemetry.addLine("RBE = Range, Bearing & Elevation");
-
- } // end method telemetryAprilTag()
-
-} // end class
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagEasy.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagEasy.java
deleted file mode 100644
index 12dcf6e9..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagEasy.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/* Copyright (c) 2023 FIRST. 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.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 recognition and pose estimation, using
- * the easy way.
- *
- * 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 have their position and orientation information displayed. 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 tag, relative to the camera.
- * This information is provided in the "ftcPose" member of the returned "detection", and is explained in the ftc-docs page linked below.
- * https://ftc-docs.firstinspires.org/apriltag-detection-values
- *
- * To experiment with using AprilTags to navigate, try out these two driving samples:
- * RobotAutoDriveToAprilTagOmni and RobotAutoDriveToAprilTagTank
- *
- * 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 Easy", group = "Concept")
-@Disabled
-public class ConceptAprilTagEasy extends LinearOpMode {
-
- private static final boolean USE_WEBCAM = true; // true for webcam, false for phone camera
-
- /**
- * 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();
-
- if (opModeIsActive()) {
- 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 the easy way.
- aprilTag = AprilTagProcessor.easyCreateWithDefaults();
-
- // Create the vision portal the easy way.
- if (USE_WEBCAM) {
- visionPortal = VisionPortal.easyCreateWithDefaults(
- hardwareMap.get(WebcamName.class, "Webcam 1"), aprilTag);
- } else {
- visionPortal = VisionPortal.easyCreateWithDefaults(
- BuiltinCameraDirection.BACK, aprilTag);
- }
-
- } // end method initAprilTag()
-
- /**
- * Add telemetry about AprilTag detections.
- */
- private void telemetryAprilTag() {
-
- List 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.ftcPose.x, detection.ftcPose.y, detection.ftcPose.z));
- telemetry.addLine(String.format("PRY %6.1f %6.1f %6.1f (deg)", detection.ftcPose.pitch, detection.ftcPose.roll, detection.ftcPose.yaw));
- telemetry.addLine(String.format("RBE %6.1f %6.1f %6.1f (inch, deg, deg)", detection.ftcPose.range, detection.ftcPose.bearing, detection.ftcPose.elevation));
- } 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)");
- telemetry.addLine("RBE = Range, Bearing & Elevation");
-
- } // end method telemetryAprilTag()
-
-} // end class
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagLocalization.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagLocalization.java
deleted file mode 100644
index d90261ef..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagLocalization.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/* 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".
- *
- * To learn about the Field Coordinate System that is defined for FTC (and used by this OpMode), see the FTC-DOCS link below:
- * https://ftc-docs.firstinspires.org/en/latest/game_specific_resources/field_coordinate_system/field-coordinate-system.html
- *
- * 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 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
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagMultiPortal.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagMultiPortal.java
deleted file mode 100644
index da5cc3ed..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagMultiPortal.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Copyright (c) 2024 FIRST. 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.vision.VisionPortal;
-import org.firstinspires.ftc.vision.apriltag.AprilTagProcessor;
-
-/**
- * This OpMode demonstrates the basics of using multiple vision portals simultaneously
- */
-@TeleOp(name = "Concept: AprilTagMultiPortal", group = "Concept")
-@Disabled
-public class ConceptAprilTagMultiPortal extends LinearOpMode
-{
- VisionPortal portal1;
- VisionPortal portal2;
-
- AprilTagProcessor aprilTagProcessor1;
- AprilTagProcessor aprilTagProcessor2;
-
- @Override
- public void runOpMode() throws InterruptedException
- {
- // Because we want to show two camera feeds simultaneously, we need to inform
- // the SDK that we want it to split the camera monitor area into two smaller
- // areas for us. It will then give us View IDs which we can pass to the individual
- // vision portals to allow them to properly hook into the UI in tandem.
- int[] viewIds = VisionPortal.makeMultiPortalView(2, VisionPortal.MultiPortalLayout.VERTICAL);
-
- // We extract the two view IDs from the array to make our lives a little easier later.
- // NB: the array is 2 long because we asked for 2 portals up above.
- int portal1ViewId = viewIds[0];
- int portal2ViewId = viewIds[1];
-
- // If we want to run AprilTag detection on two portals simultaneously,
- // we need to create two distinct instances of the AprilTag processor,
- // one for each portal. If you want to see more detail about different
- // options that you have when creating these processors, go check out
- // the ConceptAprilTag OpMode.
- aprilTagProcessor1 = AprilTagProcessor.easyCreateWithDefaults();
- aprilTagProcessor2 = AprilTagProcessor.easyCreateWithDefaults();
-
- // Now we build both portals. The CRITICAL thing to notice here is the call to
- // setLiveViewContainerId(), where we pass in the IDs we received earlier from
- // makeMultiPortalView().
- portal1 = new VisionPortal.Builder()
- .setCamera(hardwareMap.get(WebcamName.class, "Webcam 1"))
- .setLiveViewContainerId(portal1ViewId)
- .addProcessor(aprilTagProcessor1)
- .build();
- portal2 = new VisionPortal.Builder()
- .setCamera(hardwareMap.get(WebcamName.class, "Webcam 2"))
- .setLiveViewContainerId(portal2ViewId)
- .addProcessor(aprilTagProcessor2)
- .build();
-
- waitForStart();
-
- // Main Loop
- while (opModeIsActive())
- {
- // Just show some basic telemetry to demonstrate both processors are working in parallel
- // on their respective cameras. If you want to see more detail about the information you
- // can get back from the processor, you should look at ConceptAprilTag.
- telemetry.addData("Number of tags in Camera 1", aprilTagProcessor1.getDetections().size());
- telemetry.addData("Number of tags in Camera 2", aprilTagProcessor2.getDetections().size());
- telemetry.update();
- sleep(20);
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagOptimizeExposure.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagOptimizeExposure.java
deleted file mode 100644
index adee952b..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagOptimizeExposure.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/* Copyright (c) 2023 FIRST. 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 com.qualcomm.robotcore.util.Range;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.controls.ExposureControl;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.controls.GainControl;
-import org.firstinspires.ftc.vision.VisionPortal;
-import org.firstinspires.ftc.vision.apriltag.AprilTagDetection;
-import org.firstinspires.ftc.vision.apriltag.AprilTagProcessor;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/*
- * This OpMode determines the best Exposure for minimizing image motion-blur on a Webcam
- * Note that it is not possible to control the exposure for a Phone Camera, so if you are using a Phone for the Robot Controller
- * this OpMode/Feature only applies to an externally connected Webcam
- *
- * The goal is to determine the smallest (shortest) Exposure value that still provides reliable Tag Detection.
- * Starting with the minimum Exposure and maximum Gain, the exposure is slowly increased until the Tag is
- * detected reliably from the likely operational distance.
- *
- *
- * The best way to run this optimization is to view the camera preview screen while changing the exposure and gains.
- *
- * To do this, you need to view the RobotController screen directly (not from Driver Station)
- * This can be done directly from a RC phone screen (if you are using an external Webcam), but for a Control Hub you must either plug an
- * HDMI monitor into the Control Hub HDMI port, or use an external viewer program like ScrCpy (https://scrcpy.org/)
- *
- * Use Android Studio to Copy this Class, and Paste it into the TeamCode/src/main/java/org/firstinspires/ftc/teamcode folder.
- * Remove or comment out the @Disabled line to add this OpMode to the Driver Station OpMode list.
- */
-
-@TeleOp(name="Optimize AprilTag Exposure", group = "Concept")
-@Disabled
-public class ConceptAprilTagOptimizeExposure extends LinearOpMode
-{
- private VisionPortal visionPortal = null; // Used to manage the video source.
- private AprilTagProcessor aprilTag; // Used for managing the AprilTag detection process.
- private int myExposure ;
- private int minExposure ;
- private int maxExposure ;
- private int myGain ;
- private int minGain ;
- private int maxGain ;
-
- boolean thisExpUp = false;
- boolean thisExpDn = false;
- boolean thisGainUp = false;
- boolean thisGainDn = false;
-
- boolean lastExpUp = false;
- boolean lastExpDn = false;
- boolean lastGainUp = false;
- boolean lastGainDn = false;
- @Override public void runOpMode()
- {
- // Initialize the Apriltag Detection process
- initAprilTag();
-
- // Establish Min and Max Gains and Exposure. Then set a low exposure with high gain
- getCameraSetting();
- myExposure = Math.min(5, minExposure);
- myGain = maxGain;
- setManualExposure(myExposure, myGain);
-
- // Wait for the match to begin.
- telemetry.addData("Camera preview on/off", "3 dots, Camera Stream");
- telemetry.addData(">", "Touch START to start OpMode");
- telemetry.update();
- waitForStart();
-
- while (opModeIsActive())
- {
- telemetry.addLine("Find lowest Exposure that gives reliable detection.");
- telemetry.addLine("Use Left bump/trig to adjust Exposure.");
- telemetry.addLine("Use Right bump/trig to adjust Gain.\n");
-
- // Display how many Tags Detected
- List currentDetections = aprilTag.getDetections();
- int numTags = currentDetections.size();
- if (numTags > 0 )
- telemetry.addData("Tag", "####### %d Detected ######", currentDetections.size());
- else
- telemetry.addData("Tag", "----------- none - ----------");
-
- telemetry.addData("Exposure","%d (%d - %d)", myExposure, minExposure, maxExposure);
- telemetry.addData("Gain","%d (%d - %d)", myGain, minGain, maxGain);
- telemetry.update();
-
- // check to see if we need to change exposure or gain.
- thisExpUp = gamepad1.left_bumper;
- thisExpDn = gamepad1.left_trigger > 0.25;
- thisGainUp = gamepad1.right_bumper;
- thisGainDn = gamepad1.right_trigger > 0.25;
-
- // look for clicks to change exposure
- if (thisExpUp && !lastExpUp) {
- myExposure = Range.clip(myExposure + 1, minExposure, maxExposure);
- setManualExposure(myExposure, myGain);
- } else if (thisExpDn && !lastExpDn) {
- myExposure = Range.clip(myExposure - 1, minExposure, maxExposure);
- setManualExposure(myExposure, myGain);
- }
-
- // look for clicks to change the gain
- if (thisGainUp && !lastGainUp) {
- myGain = Range.clip(myGain + 1, minGain, maxGain );
- setManualExposure(myExposure, myGain);
- } else if (thisGainDn && !lastGainDn) {
- myGain = Range.clip(myGain - 1, minGain, maxGain );
- setManualExposure(myExposure, myGain);
- }
-
- lastExpUp = thisExpUp;
- lastExpDn = thisExpDn;
- lastGainUp = thisGainUp;
- lastGainDn = thisGainDn;
-
- sleep(20);
- }
- }
-
- /**
- * Initialize the AprilTag processor.
- */
- private void initAprilTag() {
- // Create the AprilTag processor by using a builder.
- aprilTag = new AprilTagProcessor.Builder().build();
-
- // Create the WEBCAM vision portal by using a builder.
- visionPortal = new VisionPortal.Builder()
- .setCamera(hardwareMap.get(WebcamName.class, "Webcam 1"))
- .addProcessor(aprilTag)
- .build();
- }
-
- /*
- Manually set the camera gain and exposure.
- Can only be called AFTER calling initAprilTag();
- Returns true if controls are set.
- */
- private boolean setManualExposure(int exposureMS, int gain) {
- // Ensure Vision Portal has been setup.
- if (visionPortal == null) {
- return false;
- }
-
- // Wait for the camera to be open
- if (visionPortal.getCameraState() != VisionPortal.CameraState.STREAMING) {
- telemetry.addData("Camera", "Waiting");
- telemetry.update();
- while (!isStopRequested() && (visionPortal.getCameraState() != VisionPortal.CameraState.STREAMING)) {
- sleep(20);
- }
- telemetry.addData("Camera", "Ready");
- telemetry.update();
- }
-
- // Set camera controls unless we are stopping.
- if (!isStopRequested())
- {
- // Set exposure. Make sure we are in Manual Mode for these values to take effect.
- ExposureControl exposureControl = visionPortal.getCameraControl(ExposureControl.class);
- if (exposureControl.getMode() != ExposureControl.Mode.Manual) {
- exposureControl.setMode(ExposureControl.Mode.Manual);
- sleep(50);
- }
- exposureControl.setExposure((long)exposureMS, TimeUnit.MILLISECONDS);
- sleep(20);
-
- // Set Gain.
- GainControl gainControl = visionPortal.getCameraControl(GainControl.class);
- gainControl.setGain(gain);
- sleep(20);
- return (true);
- } else {
- return (false);
- }
- }
-
- /*
- Read this camera's minimum and maximum Exposure and Gain settings.
- Can only be called AFTER calling initAprilTag();
- */
- private void getCameraSetting() {
- // Ensure Vision Portal has been setup.
- if (visionPortal == null) {
- return;
- }
-
- // Wait for the camera to be open
- if (visionPortal.getCameraState() != VisionPortal.CameraState.STREAMING) {
- telemetry.addData("Camera", "Waiting");
- telemetry.update();
- while (!isStopRequested() && (visionPortal.getCameraState() != VisionPortal.CameraState.STREAMING)) {
- sleep(20);
- }
- telemetry.addData("Camera", "Ready");
- telemetry.update();
- }
-
- // Get camera control values unless we are stopping.
- if (!isStopRequested()) {
- ExposureControl exposureControl = visionPortal.getCameraControl(ExposureControl.class);
- minExposure = (int)exposureControl.getMinExposure(TimeUnit.MILLISECONDS) + 1;
- maxExposure = (int)exposureControl.getMaxExposure(TimeUnit.MILLISECONDS);
-
- GainControl gainControl = visionPortal.getCameraControl(GainControl.class);
- minGain = gainControl.getMinGain();
- maxGain = gainControl.getMaxGain();
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagSwitchableCameras.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagSwitchableCameras.java
deleted file mode 100644
index 7ee1064b..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagSwitchableCameras.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/* Copyright (c) 2023 FIRST. 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.ClassFactory;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.CameraName;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName;
-import org.firstinspires.ftc.vision.VisionPortal;
-import org.firstinspires.ftc.vision.VisionPortal.CameraState;
-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 recognition and pose estimation, using
- * two webcams.
- *
- * 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 Switchable Cameras", group = "Concept")
-@Disabled
-public class ConceptAprilTagSwitchableCameras extends LinearOpMode {
-
- /*
- * Variables used for switching cameras.
- */
- private WebcamName webcam1, webcam2;
- private boolean oldLeftBumper;
- private boolean oldRightBumper;
-
- /**
- * 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();
-
- if (opModeIsActive()) {
- while (opModeIsActive()) {
-
- telemetryCameraSwitching();
- 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();
- }
-
- doCameraSwitching();
-
- // Share the CPU.
- sleep(20);
- }
- }
-
- // Save more CPU resources when camera is no longer needed.
- visionPortal.close();
-
- } // end runOpMode()
-
- /**
- * Initialize the AprilTag processor.
- */
- private void initAprilTag() {
-
- // Create the AprilTag processor by using a builder.
- aprilTag = new AprilTagProcessor.Builder().build();
-
- webcam1 = hardwareMap.get(WebcamName.class, "Webcam 1");
- webcam2 = hardwareMap.get(WebcamName.class, "Webcam 2");
- CameraName switchableCamera = ClassFactory.getInstance()
- .getCameraManager().nameForSwitchableCamera(webcam1, webcam2);
-
- // Create the vision portal by using a builder.
- visionPortal = new VisionPortal.Builder()
- .setCamera(switchableCamera)
- .addProcessor(aprilTag)
- .build();
-
- } // end method initAprilTag()
-
- /**
- * Add telemetry about camera switching.
- */
- private void telemetryCameraSwitching() {
-
- if (visionPortal.getActiveCamera().equals(webcam1)) {
- telemetry.addData("activeCamera", "Webcam 1");
- telemetry.addData("Press RightBumper", "to switch to Webcam 2");
- } else {
- telemetry.addData("activeCamera", "Webcam 2");
- telemetry.addData("Press LeftBumper", "to switch to Webcam 1");
- }
-
- } // end method telemetryCameraSwitching()
-
- /**
- * Add telemetry about AprilTag detections.
- */
- private void telemetryAprilTag() {
-
- List 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.ftcPose.x, detection.ftcPose.y, detection.ftcPose.z));
- telemetry.addLine(String.format("PRY %6.1f %6.1f %6.1f (deg)", detection.ftcPose.pitch, detection.ftcPose.roll, detection.ftcPose.yaw));
- telemetry.addLine(String.format("RBE %6.1f %6.1f %6.1f (inch, deg, deg)", detection.ftcPose.range, detection.ftcPose.bearing, detection.ftcPose.elevation));
- } 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)");
- telemetry.addLine("RBE = Range, Bearing & Elevation");
-
- } // end method telemetryAprilTag()
-
- /**
- * Set the active camera according to input from the gamepad.
- */
- private void doCameraSwitching() {
- if (visionPortal.getCameraState() == CameraState.STREAMING) {
- // If the left bumper is pressed, use Webcam 1.
- // If the right bumper is pressed, use Webcam 2.
- boolean newLeftBumper = gamepad1.left_bumper;
- boolean newRightBumper = gamepad1.right_bumper;
- if (newLeftBumper && !oldLeftBumper) {
- visionPortal.setActiveCamera(webcam1);
- } else if (newRightBumper && !oldRightBumper) {
- visionPortal.setActiveCamera(webcam2);
- }
- oldLeftBumper = newLeftBumper;
- oldRightBumper = newRightBumper;
- }
-
- } // end method doCameraSwitching()
-
-} // end class
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptExploringIMUOrientation.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptExploringIMUOrientation.java
deleted file mode 100644
index 751d54f9..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptExploringIMUOrientation.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
-Copyright (c) 2022 REV Robotics, FIRST
-
-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 REV Robotics 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.rev.RevHubOrientationOnRobot;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.IMU;
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-import org.firstinspires.ftc.robotcore.external.navigation.AngularVelocity;
-import org.firstinspires.ftc.robotcore.external.navigation.YawPitchRollAngles;
-
-/*
- * This OpMode demonstrates the impact of setting the IMU orientation correctly or incorrectly. This
- * code assumes there is an IMU configured with the name "imu".
- *
- * Note: This OpMode is more of a tool than a code sample. The User Interface portion of this code
- * goes beyond simply showing how to interface to the IMU.
- * For a minimal example of interfacing to an IMU, please see the SensorIMUOrthogonal or SensorIMUNonOrthogonal sample OpModes.
- *
- * This OpMode enables you to re-specify the Hub Mounting orientation dynamically by using gamepad controls.
- * While doing so, the sample will display how Pitch, Roll and Yaw angles change as the hub is moved.
- *
- * The gamepad controls let you change the two parameters that specify how the Control/Expansion Hub is mounted.
- * The first parameter specifies which direction the printed logo on the Hub is pointing.
- * The second parameter specifies which 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.
- *
- * How will you know if you have chosen the correct Orientation? With the correct orientation
- * parameters selected, pitch/roll/yaw should act as follows:
- *
- * Pitch value should INCREASE as the robot is tipped UP at the front. (Rotation about X)
- * Roll value should INCREASE as the robot is tipped UP at the left side. (Rotation about Y)
- * Yaw value should INCREASE as the robot is rotated Counter Clockwise. (Rotation about Z)
- *
- * The Yaw can be reset (to zero) by pressing the Y button on the gamepad (Triangle on a PS4 controller)
- *
- * The rotational velocities should follow the change in corresponding axes.
- */
-
-@TeleOp(name="Concept: IMU Orientation", group="Concept")
-@Disabled
-public class ConceptExploringIMUOrientation extends LinearOpMode {
- static RevHubOrientationOnRobot.LogoFacingDirection[] logoFacingDirections
- = RevHubOrientationOnRobot.LogoFacingDirection.values();
- static RevHubOrientationOnRobot.UsbFacingDirection[] usbFacingDirections
- = RevHubOrientationOnRobot.UsbFacingDirection.values();
- static int LAST_DIRECTION = logoFacingDirections.length - 1;
- static float TRIGGER_THRESHOLD = 0.2f;
-
- IMU imu;
- int logoFacingDirectionPosition;
- int usbFacingDirectionPosition;
- boolean orientationIsValid = true;
-
- @Override public void runOpMode() throws InterruptedException {
- imu = hardwareMap.get(IMU.class, "imu");
- logoFacingDirectionPosition = 0; // Up
- usbFacingDirectionPosition = 2; // Forward
-
- updateOrientation();
-
- boolean justChangedLogoDirection = false;
- boolean justChangedUsbDirection = false;
-
- // Loop until stop requested
- while (!isStopRequested()) {
-
- // Check to see if Yaw reset is requested (Y button)
- if (gamepad1.y) {
- telemetry.addData("Yaw", "Resetting\n");
- imu.resetYaw();
- } else {
- telemetry.addData("Yaw", "Press Y (triangle) on Gamepad to reset.\n");
- }
-
- // Check to see if new Logo Direction is requested
- if (gamepad1.left_bumper || gamepad1.right_bumper) {
- if (!justChangedLogoDirection) {
- justChangedLogoDirection = true;
- if (gamepad1.left_bumper) {
- logoFacingDirectionPosition--;
- if (logoFacingDirectionPosition < 0) {
- logoFacingDirectionPosition = LAST_DIRECTION;
- }
- } else {
- logoFacingDirectionPosition++;
- if (logoFacingDirectionPosition > LAST_DIRECTION) {
- logoFacingDirectionPosition = 0;
- }
- }
- updateOrientation();
- }
- } else {
- justChangedLogoDirection = false;
- }
-
- // Check to see if new USB Direction is requested
- if (gamepad1.left_trigger > TRIGGER_THRESHOLD || gamepad1.right_trigger > TRIGGER_THRESHOLD) {
- if (!justChangedUsbDirection) {
- justChangedUsbDirection = true;
- if (gamepad1.left_trigger > TRIGGER_THRESHOLD) {
- usbFacingDirectionPosition--;
- if (usbFacingDirectionPosition < 0) {
- usbFacingDirectionPosition = LAST_DIRECTION;
- }
- } else {
- usbFacingDirectionPosition++;
- if (usbFacingDirectionPosition > LAST_DIRECTION) {
- usbFacingDirectionPosition = 0;
- }
- }
- updateOrientation();
- }
- } else {
- justChangedUsbDirection = false;
- }
-
- // Display User instructions and IMU data
- telemetry.addData("logo Direction (set with bumpers)", logoFacingDirections[logoFacingDirectionPosition]);
- telemetry.addData("usb Direction (set with triggers)", usbFacingDirections[usbFacingDirectionPosition] + "\n");
-
- if (orientationIsValid) {
- YawPitchRollAngles orientation = imu.getRobotYawPitchRollAngles();
- AngularVelocity angularVelocity = imu.getRobotAngularVelocity(AngleUnit.DEGREES);
-
- telemetry.addData("Yaw (Z)", "%.2f Deg. (Heading)", orientation.getYaw(AngleUnit.DEGREES));
- telemetry.addData("Pitch (X)", "%.2f Deg.", orientation.getPitch(AngleUnit.DEGREES));
- telemetry.addData("Roll (Y)", "%.2f Deg.\n", orientation.getRoll(AngleUnit.DEGREES));
- telemetry.addData("Yaw (Z) velocity", "%.2f Deg/Sec", angularVelocity.zRotationRate);
- telemetry.addData("Pitch (X) velocity", "%.2f Deg/Sec", angularVelocity.xRotationRate);
- telemetry.addData("Roll (Y) velocity", "%.2f Deg/Sec", angularVelocity.yRotationRate);
- } else {
- telemetry.addData("Error", "Selected orientation on robot is invalid");
- }
-
- telemetry.update();
- }
- }
-
- // apply any requested orientation changes.
- void updateOrientation() {
- RevHubOrientationOnRobot.LogoFacingDirection logo = logoFacingDirections[logoFacingDirectionPosition];
- RevHubOrientationOnRobot.UsbFacingDirection usb = usbFacingDirections[usbFacingDirectionPosition];
- try {
- RevHubOrientationOnRobot orientationOnRobot = new RevHubOrientationOnRobot(logo, usb);
- imu.initialize(new IMU.Parameters(orientationOnRobot));
- orientationIsValid = true;
- } catch (IllegalArgumentException e) {
- orientationIsValid = false;
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptExternalHardwareClass.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptExternalHardwareClass.java
deleted file mode 100644
index 7a721fef..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptExternalHardwareClass.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Copyright (c) 2022 FIRST. 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 com.qualcomm.robotcore.util.Range;
-
-/*
- * This OpMode illustrates how to use an external "hardware" class to modularize all the robot's sensors and actuators.
- * This approach is very efficient because the same hardware class can be used by all of your teleop and autonomous OpModes
- * without requiring many copy & paste operations. Once you have defined and tested the hardware class with one OpMode,
- * it is instantly available to other OpModes.
- *
- * The real benefit of this approach is that as you tweak your robot hardware, you only need to make changes in ONE place (the Hardware Class).
- * So, to be effective you should put as much or your hardware setup and access code as possible in the hardware class.
- * Essentially anything you do with hardware in BOTH Teleop and Auto should likely go in the hardware class.
- *
- * The Hardware Class is created in a separate file, and then an "instance" of this class is created in each OpMode.
- * In order for the class to do typical OpMode things (like send telemetry data) it must be passed a reference to the
- * OpMode object when it's created, so it can access all core OpMode functions. This is illustrated below.
- *
- * In this concept sample, the hardware class file is called RobotHardware.java and it must accompany this sample OpMode.
- * So, if you copy ConceptExternalHardwareClass.java into TeamCode (using Android Studio or OnBotJava) then RobotHardware.java
- * must also be copied to the same location (maintaining its name).
- *
- * For comparison purposes, this sample and its accompanying hardware class duplicates the functionality of the
- * RobotTelopPOV_Linear OpMode. It assumes three motors (left_drive, right_drive and arm) and two servos (left_hand and right_hand)
- *
- * View the RobotHardware.java class file for more details
- *
- * 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
- *
- * In OnBot Java, add a new OpMode, select this sample, and select TeleOp.
- * Also add another new file named RobotHardware.java, select the sample with that name, and select Not an OpMode.
- */
-
-@TeleOp(name="Concept: Robot Hardware Class", group="Robot")
-@Disabled
-public class ConceptExternalHardwareClass extends LinearOpMode {
-
- // Create a RobotHardware object to be used to access robot hardware.
- // Prefix any hardware functions with "robot." to access this class.
- RobotHardware robot = new RobotHardware(this);
-
- @Override
- public void runOpMode() {
- double drive = 0;
- double turn = 0;
- double arm = 0;
- double handOffset = 0;
-
- // initialize all the hardware, using the hardware class. See how clean and simple this is?
- robot.init();
-
- // Send telemetry message to signify robot waiting;
- // Wait for the game to start (driver presses START)
- waitForStart();
-
- // run until the end of the match (driver presses STOP)
- while (opModeIsActive()) {
-
- // Run wheels in POV mode (note: The joystick goes negative when pushed forward, so negate it)
- // In this mode the Left stick moves the robot fwd and back, the Right stick turns left and right.
- // This way it's also easy to just drive straight, or just turn.
- drive = -gamepad1.left_stick_y;
- turn = gamepad1.right_stick_x;
-
- // Combine drive and turn for blended motion. Use RobotHardware class
- robot.driveRobot(drive, turn);
-
- // Use gamepad left & right Bumpers to open and close the claw
- // Use the SERVO constants defined in RobotHardware class.
- // Each time around the loop, the servos will move by a small amount.
- // Limit the total offset to half of the full travel range
- if (gamepad1.right_bumper)
- handOffset += robot.HAND_SPEED;
- else if (gamepad1.left_bumper)
- handOffset -= robot.HAND_SPEED;
- handOffset = Range.clip(handOffset, -0.5, 0.5);
-
- // Move both servos to new position. Use RobotHardware class
- robot.setHandPositions(handOffset);
-
- // Use gamepad buttons to move arm up (Y) and down (A)
- // Use the MOTOR constants defined in RobotHardware class.
- if (gamepad1.y)
- arm = robot.ARM_UP_POWER;
- else if (gamepad1.a)
- arm = robot.ARM_DOWN_POWER;
- else
- arm = 0;
-
- robot.setArmPower(arm);
-
- // Send telemetry messages to explain controls and show robot status
- telemetry.addData("Drive", "Left Stick");
- telemetry.addData("Turn", "Right Stick");
- telemetry.addData("Arm Up/Down", "Y & A Buttons");
- telemetry.addData("Hand Open/Closed", "Left and Right Bumpers");
- telemetry.addData("-", "-------");
-
- telemetry.addData("Drive Power", "%.2f", drive);
- telemetry.addData("Turn Power", "%.2f", turn);
- telemetry.addData("Arm Power", "%.2f", arm);
- telemetry.addData("Hand Position", "Offset = %.2f", handOffset);
- telemetry.update();
-
- // Pace this loop so hands move at a reasonable speed.
- sleep(50);
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptGamepadRumble.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptGamepadRumble.java
deleted file mode 100644
index cf846e18..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptGamepadRumble.java
+++ /dev/null
@@ -1,200 +0,0 @@
-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 com.qualcomm.robotcore.hardware.Gamepad;
-import com.qualcomm.robotcore.util.ElapsedTime;
-
-/*
- * This OpMode illustrates using the rumble feature of many gamepads.
- *
- * Note: Some gamepads "rumble" better than others.
- * The Xbox & PS4 have a left (rumble1) and right (rumble2) rumble motor.
- * These two gamepads have two distinct rumble modes: Large on the left, and small on the right
- * The Etpark gamepad may only respond to rumble1, and may only run at full power.
- * The Logitech F310 gamepad does not have *any* rumble ability.
- *
- * Moral: You should use this sample to experiment with your specific gamepads to explore their rumble features.
- *
- * The rumble motors are accessed through the standard gamepad1 and gamepad2 objects.
- * Several new methods were added to the Gamepad class in FTC SDK Rev 7
- * The key methods are as follows:
- *
- * .rumble(double rumble1, double rumble2, int durationMs)
- * This method sets the rumble power of both motors for a specific time duration.
- * Both rumble arguments are motor-power levels in the 0.0 to 1.0 range.
- * durationMs is the desired length of the rumble action in milliseconds.
- * This method returns immediately.
- * Note:
- * Use a durationMs of Gamepad.RUMBLE_DURATION_CONTINUOUS to provide a continuous rumble
- * Use a power of 0, or duration of 0 to stop a rumble.
- *
- * .rumbleBlips(int count) allows an easy way to signal the driver with a series of rumble blips.
- * Just specify how many blips you want.
- * This method returns immediately.
- *
- * .runRumbleEffect(customRumbleEffect) allows you to run a custom rumble sequence that you have
- * built using the Gamepad.RumbleEffect.Builder()
- * A "custom effect" is a sequence of steps, where each step can rumble any of the
- * rumble motors for a specific period at a specific power level.
- * The Custom Effect will play as the (un-blocked) OpMode continues to run
- *
- * .isRumbling() returns true if there is a rumble effect in progress.
- * Use this call to prevent stepping on a current rumble.
- *
- * .stopRumble() Stop any ongoing rumble or custom rumble effect.
- *
- * .rumble(int durationMs) Full power rumble for fixed duration.
- *
- * Note: Whenever a new Rumble command is issued, any currently executing rumble action will
- * be truncated, and the new action started immediately. Take these precautions:
- * 1) Do Not SPAM the rumble motors by issuing rapid fire commands
- * 2) Multiple sources for rumble commands must coordinate to avoid tromping on each other.
- *
- * This can be achieved several possible ways:
- * 1) Only having one source for rumble actions
- * 2) Issuing rumble commands on transitions, rather than states.
- * e.g. The moment a touch sensor is pressed, rather than the entire time it is being pressed.
- * 3) Scheduling rumble commands based on timed events. e.g. 10 seconds prior to endgame
- * 4) Rumble on non-overlapping mechanical actions. e.g. arm fully-extended or fully-retracted.
- * 5) Use isRumbling() to hold off on a new rumble if one is already in progress.
- *
- * The examples shown here are representstive of how to invoke a gamepad rumble.
- * It is assumed that these will be modified to suit the specific robot and team strategy needs.
- *
- * ######## Read the telemetry display on the Driver Station Screen for instructions. ######
- *
- * Ex 1) This example shows a) how to create a custom rumble effect, and then b) how to trigger it based
- * on game time. One use for this might be to alert the driver that half-time or End-game is approaching.
- *
- * Ex 2) This example shows tying the rumble power to a changing sensor value.
- * In this case it is the Gamepad trigger, but it could be any sensor output scaled to the 0-1 range.
- * Since it takes over the rumble motors, it is only performed when the Left Bumper is pressed.
- * Note that this approach MUST include a way to turn OFF the rumble when the button is released.
- *
- * Ex 3) This example shows a simple way to trigger a 3-blip sequence. In this case it is
- * triggered by the gamepad A (Cross) button, but it could be any sensor, like a touch or light sensor.
- * Note that this code ensures that it only rumbles once when the input goes true.
- *
- * Ex 4) This example shows how to trigger a single rumble when an input value gets over a certain value.
- * In this case it is reading the Right Trigger, but it could be any variable sensor, like a
- * range sensor, or position sensor. The code needs to ensure that it is only triggered once, so
- * it waits till the sensor drops back below the threshold before it can trigger again.
- *
- * 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.
- */
-
-@Disabled
-@TeleOp(name="Concept: Gamepad Rumble", group ="Concept")
-public class ConceptGamepadRumble extends LinearOpMode
-{
- boolean lastA = false; // Use to track the prior button state.
- boolean lastLB = false; // Use to track the prior button state.
- boolean highLevel = false; // used to prevent multiple level-based rumbles.
- boolean secondHalf = false; // Use to prevent multiple half-time warning rumbles.
-
- Gamepad.RumbleEffect customRumbleEffect; // Use to build a custom rumble sequence.
- ElapsedTime runtime = new ElapsedTime(); // Use to determine when end game is starting.
-
- final double HALF_TIME = 60.0; // Wait this many seconds before rumble-alert for half-time.
- final double TRIGGER_THRESHOLD = 0.75; // Squeeze more than 3/4 to get rumble.
-
- @Override
- public void runOpMode()
- {
- // Example 1. a) start by creating a three-pulse rumble sequence: right, LEFT, LEFT
- customRumbleEffect = new Gamepad.RumbleEffect.Builder()
- .addStep(0.0, 1.0, 500) // Rumble right motor 100% for 500 mSec
- .addStep(0.0, 0.0, 300) // Pause for 300 mSec
- .addStep(1.0, 0.0, 250) // Rumble left motor 100% for 250 mSec
- .addStep(0.0, 0.0, 250) // Pause for 250 mSec
- .addStep(1.0, 0.0, 250) // Rumble left motor 100% for 250 mSec
- .build();
-
- telemetry.addData(">", "Press Start");
- telemetry.update();
-
- waitForStart();
- runtime.reset(); // Start game timer.
-
- // Loop while monitoring buttons for rumble triggers
- while (opModeIsActive())
- {
- // Read and save the current gamepad button states.
- boolean currentA = gamepad1.a ;
- boolean currentLB = gamepad1.left_bumper ;
-
- // Display the current Rumble status. Just for interest.
- telemetry.addData(">", "Are we RUMBLING? %s\n", gamepad1.isRumbling() ? "YES" : "no" );
-
- // ----------------------------------------------------------------------------------------
- // Example 1. b) Watch the runtime timer, and run the custom rumble when we hit half-time.
- // Make sure we only signal once by setting "secondHalf" flag to prevent further rumbles.
- // ----------------------------------------------------------------------------------------
- if ((runtime.seconds() > HALF_TIME) && !secondHalf) {
- gamepad1.runRumbleEffect(customRumbleEffect);
- secondHalf =true;
- }
-
- // Display the time remaining while we are still counting down.
- if (!secondHalf) {
- telemetry.addData(">", "Halftime Alert Countdown: %3.0f Sec \n", (HALF_TIME - runtime.seconds()) );
- }
-
-
- // ----------------------------------------------------------------------------------------
- // Example 2. If Left Bumper is being pressed, power the rumble motors based on the two trigger depressions.
- // This is useful to see how the rumble feels at various power levels.
- // ----------------------------------------------------------------------------------------
- if (currentLB) {
- // Left Bumper is being pressed, so send left and right "trigger" values to left and right rumble motors.
- gamepad1.rumble(gamepad1.left_trigger, gamepad1.right_trigger, Gamepad.RUMBLE_DURATION_CONTINUOUS);
-
- // Show what is being sent to rumbles
- telemetry.addData(">", "Squeeze triggers to control rumbles");
- telemetry.addData("> : Rumble", "Left: %.0f%% Right: %.0f%%", gamepad1.left_trigger * 100, gamepad1.right_trigger * 100);
- } else {
- // Make sure rumble is turned off when Left Bumper is released (only one time each press)
- if (lastLB) {
- gamepad1.stopRumble();
- }
-
- // Prompt for manual rumble action
- telemetry.addData(">", "Hold Left-Bumper to test Manual Rumble");
- telemetry.addData(">", "Press A (Cross) for three blips");
- telemetry.addData(">", "Squeeze right trigger slowly for 1 blip");
- }
- lastLB = currentLB; // remember the current button state for next time around the loop
-
-
- // ----------------------------------------------------------------------------------------
- // Example 3. Blip 3 times at the moment that A (Cross) is pressed. (look for pressed transition)
- // BUT !!! Skip it altogether if the Gamepad is already rumbling.
- // ----------------------------------------------------------------------------------------
- if (currentA && !lastA) {
- if (!gamepad1.isRumbling()) // Check for possible overlap of rumbles.
- gamepad1.rumbleBlips(3);
- }
- lastA = currentA; // remember the current button state for next time around the loop
-
-
- // ----------------------------------------------------------------------------------------
- // Example 4. Rumble once when gamepad right trigger goes above the THRESHOLD.
- // ----------------------------------------------------------------------------------------
- if (gamepad1.right_trigger > TRIGGER_THRESHOLD) {
- if (!highLevel) {
- gamepad1.rumble(0.9, 0, 200); // 200 mSec burst on left motor.
- highLevel = true; // Hold off any more triggers
- }
- } else {
- highLevel = false; // We can trigger again now.
- }
-
- // Send the telemetry data to the Driver Station, and then pause to pace the program.
- telemetry.update();
- sleep(10);
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptGamepadTouchpad.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptGamepadTouchpad.java
deleted file mode 100644
index 84d8cec9..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptGamepadTouchpad.java
+++ /dev/null
@@ -1,77 +0,0 @@
-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.Telemetry;
-
-/*
- * This OpMode illustrates using the touchpad feature found on some gamepads.
- *
- * The Sony PS4 gamepad can detect two distinct touches on the central touchpad.
- * Other gamepads with different touchpads may provide mixed results.
- *
- * The touchpads are accessed through the standard gamepad1 and gamepad2 objects.
- * Several new members were added to the Gamepad class in FTC SDK Rev 7
- *
- * .touchpad_finger_1 returns true if at least one finger is detected.
- * .touchpad_finger_1_x finger 1 X coordinate. Valid if touchpad_finger_1 is true
- * .touchpad_finger_1_y finger 1 Y coordinate. Valid if touchpad_finger_1 is true
- *
- * .touchpad_finger_2 returns true if a second finger is detected
- * .touchpad_finger_2_x finger 2 X coordinate. Valid if touchpad_finger_2 is true
- * .touchpad_finger_2_y finger 2 Y coordinate. Valid if touchpad_finger_2 is true
- *
- * Finger touches are reported with an X and Y coordinate in following coordinate system.
- *
- * 1) X is the Horizontal axis, and Y is the vertical axis
- * 2) The 0,0 origin is at the center of the touchpad.
- * 3) 1.0, 1.0 is at the top right corner of the touchpad.
- * 4) -1.0,-1.0 is at the bottom left corner of the touchpad.
- *
- * 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.
- */
-
-@Disabled
-@TeleOp(name="Concept: Gamepad Touchpad", group ="Concept")
-public class ConceptGamepadTouchpad extends LinearOpMode
-{
- @Override
- public void runOpMode()
- {
- telemetry.setDisplayFormat(Telemetry.DisplayFormat.MONOSPACE);
-
- telemetry.addData(">", "Press Start");
- telemetry.update();
-
- waitForStart();
-
- while (opModeIsActive())
- {
- boolean finger = false;
-
- // Display finger 1 x & y position if finger detected
- if(gamepad1.touchpad_finger_1)
- {
- finger = true;
- telemetry.addLine(String.format("Finger 1: x=%5.2f y=%5.2f\n", gamepad1.touchpad_finger_1_x, gamepad1.touchpad_finger_1_y));
- }
-
- // Display finger 2 x & y position if finger detected
- if(gamepad1.touchpad_finger_2)
- {
- finger = true;
- telemetry.addLine(String.format("Finger 2: x=%5.2f y=%5.2f\n", gamepad1.touchpad_finger_2_x, gamepad1.touchpad_finger_2_y));
- }
-
- if(!finger)
- {
- telemetry.addLine("No fingers");
- }
-
- telemetry.update();
- sleep(10);
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptLEDStick.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptLEDStick.java
deleted file mode 100644
index 01729bbb..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptLEDStick.java
+++ /dev/null
@@ -1,123 +0,0 @@
-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;
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptMotorBulkRead.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptMotorBulkRead.java
deleted file mode 100644
index 5439f780..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptMotorBulkRead.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/* Copyright (c) 2019 Phil Malone. 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.lynx.LynxModule;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.DcMotorEx;
-import com.qualcomm.robotcore.util.ElapsedTime;
-
-import java.util.List;
-
-/*
- * This OpMode illustrates how to use the Expansion Hub's Bulk-Read feature to speed up control cycle times.
- * In this example there are 4 motors that need their encoder positions, and velocities read.
- * The sample is written to work with one or two expansion hubs, with no assumption as to where the motors are located.
- *
- * Three scenarios are tested:
- * Cache Mode = OFF This is the normal default, where no cache is used, and every read produces a discrete transaction with
- * an expansion hub, which is the slowest approach, but guarentees that the value is as fresh (recent) as possible..
- *
- * Cache Mode = AUTO This mode will attempt to minimize the number of discrete read commands, by performing bulk-reads
- * and then returning values that have been cached. The cache is updated automatically whenever any specific encoder is re-read.
- * This mode will always return new data, but it may perform more bulk-reads than absolutely required.
- * Extra reads will be performed if multiple encoder/velocity reads are performed on the same encoder in one control cycle.
- * This mode is a good compromise between the OFF and MANUAL modes.
- * Note: If there are significant user-program delays between encoder reads, the cached value may not be fresh (recent).
- * You can issue a clearBulkCache() call at any time force a fresh bulk-read on the next encoder read.
- *
- * Cache Mode = MANUAL This mode requires the user's code to determine the best time to clear the cached bulk-read data.
- * Well organized code will reset the cache once at the beginning of the control cycle, and then immediately read and store all the encoder values.
- * This approach will produce the shortest cycle times, but it does require the user to manually clear the cache.
- * Since NO automatic Bulk-Reads are performed, neglecting to clear the bulk cache will result in the same values being returned
- * each time an encoder read is performed.
- *
- * -------------------------------------
- *
- * General tip to speed up your control cycles:
- *
- * No matter what method you use to read encoders and other inputs, you should try to
- * avoid reading the same encoder input multiple times around a control loop.
- * Under normal conditions, this will slow down the control loop.
- * The preferred method is to read all the required inputs ONCE at the beginning of the loop,
- * and save the values in variable that can be used by other parts of the control code.
- *
- * eg: if you are sending encoder positions to your telemetry display, putting a getCurrentPosition()
- * call in the telemetry statement will force the code to go and get another copy which will take time.
- * It's much better read the position into a variable once, and use that variable for control AND display.
- * Reading saved variables takes no time at all.
- *
- * Once you put all your sensor reads at the beginning of the control cycle, it's very easy to use
- * the bulk-read AUTO mode to streamline your cycle timing.
- */
-@TeleOp (name = "Motor Bulk Reads", group = "Tests")
-@Disabled
-public class ConceptMotorBulkRead extends LinearOpMode {
-
- final int TEST_CYCLES = 500; // Number of control cycles to run to determine cycle times.
-
- private DcMotorEx m1, m2, m3, m4; // Motor Objects
- private long e1, e2, e3, e4; // Encoder Values
- private double v1, v2, v3, v4; // Velocities
-
- // Cycle Times
- double t1 = 0;
- double t2 = 0;
- double t3 = 0;
-
- @Override
- public void runOpMode() {
-
- int cycles;
-
- // Important Step 1: Make sure you use DcMotorEx when you instantiate your motors.
- m1 = hardwareMap.get(DcMotorEx.class, "m1"); // Configure the robot to use these 4 motor names,
- m2 = hardwareMap.get(DcMotorEx.class, "m2"); // or change these strings to match your existing Robot Configuration.
- m3 = hardwareMap.get(DcMotorEx.class, "m3");
- m4 = hardwareMap.get(DcMotorEx.class, "m4");
-
- // Important Step 2: Get access to a list of Expansion Hub Modules to enable changing caching methods.
- List allHubs = hardwareMap.getAll(LynxModule.class);
-
- ElapsedTime timer = new ElapsedTime();
-
- telemetry.addData(">", "Press START to start tests");
- telemetry.addData(">", "Test results will update for each access method.");
- telemetry.update();
- waitForStart();
-
- // --------------------------------------------------------------------------------------
- // Run control loop using legacy encoder reads
- // In this mode, a single read is done for each encoder position, and a bulk read is done for each velocity read.
- // This is the worst case scenario.
- // This is the same as using LynxModule.BulkCachingMode.OFF
- // --------------------------------------------------------------------------------------
-
- displayCycleTimes("Test 1 of 3 (Wait for completion)");
-
- timer.reset();
- cycles = 0;
- while (opModeIsActive() && (cycles++ < TEST_CYCLES)) {
- e1 = m1.getCurrentPosition();
- e2 = m2.getCurrentPosition();
- e3 = m3.getCurrentPosition();
- e4 = m4.getCurrentPosition();
-
- v1 = m1.getVelocity();
- v2 = m2.getVelocity();
- v3 = m3.getVelocity();
- v4 = m4.getVelocity();
-
- // Put Control loop action code here.
-
- }
- // calculate the average cycle time.
- t1 = timer.milliseconds() / cycles;
- displayCycleTimes("Test 2 of 3 (Wait for completion)");
-
- // --------------------------------------------------------------------------------------
- // Run test cycles using AUTO cache mode
- // In this mode, only one bulk read is done per cycle, UNLESS you read a specific encoder/velocity item AGAIN in that cycle.
- // --------------------------------------------------------------------------------------
-
- // Important Step 3: Option A. Set all Expansion hubs to use the AUTO Bulk Caching mode
- for (LynxModule module : allHubs) {
- module.setBulkCachingMode(LynxModule.BulkCachingMode.AUTO);
- }
-
- timer.reset();
- cycles = 0;
- while (opModeIsActive() && (cycles++ < TEST_CYCLES)) {
- e1 = m1.getCurrentPosition(); // Uses 1 bulk-read for all 4 encoder/velocity reads,
- e2 = m2.getCurrentPosition(); // but don't do any `get` operations more than once per cycle.
- e3 = m3.getCurrentPosition();
- e4 = m4.getCurrentPosition();
-
- v1 = m1.getVelocity();
- v2 = m2.getVelocity();
- v3 = m3.getVelocity();
- v4 = m4.getVelocity();
-
- // Put Control loop action code here.
-
- }
- // calculate the average cycle time.
- t2 = timer.milliseconds() / cycles;
- displayCycleTimes("Test 3 of 3 (Wait for completion)");
-
- // --------------------------------------------------------------------------------------
- // Run test cycles using MANUAL cache mode
- // In this mode, only one block read is done each control cycle.
- // This is the MOST efficient method, but it does require that the cache is cleared manually each control cycle.
- // --------------------------------------------------------------------------------------
-
- // Important Step 3: Option B. Set all Expansion hubs to use the MANUAL Bulk Caching mode
- for (LynxModule module : allHubs) {
- module.setBulkCachingMode(LynxModule.BulkCachingMode.MANUAL);
- }
-
- timer.reset();
- cycles = 0;
- while (opModeIsActive() && (cycles++ < TEST_CYCLES)) {
-
- // Important Step 4: If you are using MANUAL mode, you must clear the BulkCache once per control cycle
- for (LynxModule module : allHubs) {
- module.clearBulkCache();
- }
-
- e1 = m1.getCurrentPosition(); // Uses 1 bulk-read to obtain ALL the motor data
- e2 = m2.getCurrentPosition(); // There is no penalty for doing more `get` operations in this cycle,
- e3 = m3.getCurrentPosition(); // but they will return the same data.
- e4 = m4.getCurrentPosition();
-
- v1 = m1.getVelocity();
- v2 = m2.getVelocity();
- v3 = m3.getVelocity();
- v4 = m4.getVelocity();
-
- // Put Control loop action code here.
-
- }
- // calculate the average cycle time.
- t3 = timer.milliseconds() / cycles;
- displayCycleTimes("Complete");
-
- // wait until op-mode is stopped by user, before clearing display.
- while (opModeIsActive()) ;
- }
-
- // Display three comparison times.
- void displayCycleTimes(String status) {
- telemetry.addData("Testing", status);
- telemetry.addData("Cache = OFF", "%5.1f mS/cycle", t1);
- telemetry.addData("Cache = AUTO", "%5.1f mS/cycle", t2);
- telemetry.addData("Cache = MANUAL", "%5.1f mS/cycle", t3);
- telemetry.update();
- }
-}
-
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptNullOp.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptNullOp.java
deleted file mode 100644
index 4a887bda..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptNullOp.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.OpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.util.ElapsedTime;
-
-/*
- * Demonstrates an empty iterative OpMode
- */
-@TeleOp(name = "Concept: NullOp", group = "Concept")
-@Disabled
-public class ConceptNullOp extends OpMode {
-
- private ElapsedTime runtime = new ElapsedTime();
-
- /**
- * This method will be called once, when the INIT button is pressed.
- */
- @Override
- public void init() {
- telemetry.addData("Status", "Initialized");
- }
-
- /**
- * This method will be called repeatedly during the period between when
- * the INIT button is pressed and when the START button is pressed (or the
- * OpMode is stopped).
- */
- @Override
- public void init_loop() {
- }
-
- /**
- * This method will be called once, when the START button is pressed.
- */
- @Override
- public void start() {
- runtime.reset();
- }
-
- /**
- * This method will be called repeatedly during the period between when
- * the START button is pressed and when the OpMode is stopped.
- */
- @Override
- public void loop() {
- telemetry.addData("Status", "Run Time: " + runtime.toString());
- }
-
- /**
- * This method will be called once, when this OpMode is stopped.
- *
- * Your ability to control hardware from this method will be limited.
- */
- @Override
- public void stop() {
-
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRampMotorSpeed.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRampMotorSpeed.java
deleted file mode 100644
index 6e0be376..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRampMotorSpeed.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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 com.qualcomm.robotcore.hardware.DcMotor;
-
-/*
- * This OpMode ramps a single motor speed up and down repeatedly until Stop is pressed.
- * The code is structured as a LinearOpMode
- *
- * This code assumes a DC motor configured with the name "left_drive" as is found on a Robot.
- *
- * INCREMENT sets how much to increase/decrease the power each cycle
- * CYCLE_MS sets the update period.
- *
- * 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: Ramp Motor Speed", group = "Concept")
-@Disabled
-public class ConceptRampMotorSpeed extends LinearOpMode {
-
- static final double INCREMENT = 0.01; // amount to ramp motor each CYCLE_MS cycle
- static final int CYCLE_MS = 50; // period of each cycle
- static final double MAX_FWD = 1.0; // Maximum FWD power applied to motor
- static final double MAX_REV = -1.0; // Maximum REV power applied to motor
-
- // Define class members
- DcMotor motor;
- double power = 0;
- boolean rampUp = true;
-
-
- @Override
- public void runOpMode() {
-
- // Connect to motor (Assume standard left wheel)
- // Change the text in quotes to match any motor name on your robot.
- motor = hardwareMap.get(DcMotor.class, "left_drive");
-
- // Wait for the start button
- telemetry.addData(">", "Press Start to run Motors." );
- telemetry.update();
- waitForStart();
-
- // Ramp motor speeds till stop pressed.
- while(opModeIsActive()) {
-
- // Ramp the motors, according to the rampUp variable.
- if (rampUp) {
- // Keep stepping up until we hit the max value.
- power += INCREMENT ;
- if (power >= MAX_FWD ) {
- power = MAX_FWD;
- rampUp = !rampUp; // Switch ramp direction
- }
- }
- else {
- // Keep stepping down until we hit the min value.
- power -= INCREMENT ;
- if (power <= MAX_REV ) {
- power = MAX_REV;
- rampUp = !rampUp; // Switch ramp direction
- }
- }
-
- // Display the current value
- telemetry.addData("Motor Power", "%5.2f", power);
- telemetry.addData(">", "Press Stop to end test." );
- telemetry.update();
-
- // Set the motor to the new power and pause;
- motor.setPower(power);
- sleep(CYCLE_MS);
- idle();
- }
-
- // Turn off motor and signal done;
- motor.setPower(0);
- telemetry.addData(">", "Done");
- telemetry.update();
-
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRevLED.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRevLED.java
deleted file mode 100644
index 9c168d50..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRevLED.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- 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();
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRevSPARKMini.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRevSPARKMini.java
deleted file mode 100644
index 798d6893..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRevSPARKMini.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Copyright (c) 2018 FIRST. 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 com.qualcomm.robotcore.hardware.DcMotorSimple;
-import com.qualcomm.robotcore.util.ElapsedTime;
-import com.qualcomm.robotcore.util.Range;
-
-
-/*
- * This OpMode demonstrates a POV Drive system, with commented-out code for a Tank Drive system,
- * 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'
- * and name them 'left_drive' and 'right_drive'.
- *
- * 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="REV SPARKmini Simple Drive Example", group="Concept")
-@Disabled
-public class ConceptRevSPARKMini extends LinearOpMode {
-
- // Declare OpMode members.
- private ElapsedTime runtime = new ElapsedTime();
- private DcMotorSimple leftDrive = null;
- private DcMotorSimple rightDrive = null;
-
- @Override
- public void runOpMode() {
- telemetry.addData("Status", "Initialized");
- telemetry.update();
-
- // Initialize the hardware variables. Note that the strings used here as parameters
- // to 'get' must correspond to the names assigned during robot configuration.
- leftDrive = hardwareMap.get(DcMotorSimple.class, "left_drive");
- rightDrive = hardwareMap.get(DcMotorSimple.class, "right_drive");
-
- // Most robots need the motor on one side to be reversed to drive forward
- // Reverse the motor that runs backward when connected directly to the battery
- leftDrive.setDirection(DcMotorSimple.Direction.FORWARD);
- rightDrive.setDirection(DcMotorSimple.Direction.REVERSE);
-
- // Wait for the game to start (driver presses START)
- waitForStart();
- runtime.reset();
-
- // run until the end of the match (driver presses STOP)
- while (opModeIsActive()) {
-
- // Setup a variable for each drive wheel to save power level for telemetry
- double leftPower;
- double rightPower;
-
- // Choose to drive using either Tank Mode, or POV Mode
- // Comment out the method that's not used. The default below is POV.
-
- // POV Mode uses left stick to go forward, and right stick to turn.
- // - This uses basic math to combine motions and is easier to drive straight.
- double drive = -gamepad1.left_stick_y;
- double turn = gamepad1.right_stick_x;
- leftPower = Range.clip(drive + turn, -1.0, 1.0) ;
- rightPower = Range.clip(drive - turn, -1.0, 1.0) ;
-
- // Tank Mode uses one stick to control each wheel.
- // - This requires no math, but it is hard to drive forward slowly and keep straight.
- // leftPower = -gamepad1.left_stick_y ;
- // rightPower = -gamepad1.right_stick_y ;
-
- // Send calculated power to wheels
- leftDrive.setPower(leftPower);
- rightDrive.setPower(rightPower);
-
- // Show the elapsed game time and wheel power.
- telemetry.addData("Status", "Run Time: " + runtime.toString());
- telemetry.addData("Motors", "left (%.2f), right (%.2f)", leftPower, rightPower);
- telemetry.update();
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptScanServo.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptScanServo.java
deleted file mode 100644
index 2b8ad332..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptScanServo.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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 com.qualcomm.robotcore.hardware.Servo;
-
-/*
- * This OpMode scans a single servo back and forward until Stop is pressed.
- * The code is structured as a LinearOpMode
- * INCREMENT sets how much to increase/decrease the servo position each cycle
- * CYCLE_MS sets the update period.
- *
- * This code assumes a Servo configured with the name "left_hand" as is found on a Robot.
- *
- * NOTE: When any servo position is set, ALL attached servos are activated, so ensure that any other
- * connected servos are able to move freely before running this test.
- *
- * 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: Scan Servo", group = "Concept")
-@Disabled
-public class ConceptScanServo extends LinearOpMode {
-
- static final double INCREMENT = 0.01; // amount to slew servo each CYCLE_MS cycle
- static final int CYCLE_MS = 50; // period of each cycle
- static final double MAX_POS = 1.0; // Maximum rotational position
- static final double MIN_POS = 0.0; // Minimum rotational position
-
- // Define class members
- Servo servo;
- double position = (MAX_POS - MIN_POS) / 2; // Start at halfway position
- boolean rampUp = true;
-
-
- @Override
- public void runOpMode() {
-
- // Connect to servo (Assume Robot Left Hand)
- // Change the text in quotes to match any servo name on your robot.
- servo = hardwareMap.get(Servo.class, "left_hand");
-
- // Wait for the start button
- telemetry.addData(">", "Press Start to scan Servo." );
- telemetry.update();
- waitForStart();
-
-
- // Scan servo till stop pressed.
- while(opModeIsActive()){
-
- // slew the servo, according to the rampUp (direction) variable.
- if (rampUp) {
- // Keep stepping up until we hit the max value.
- position += INCREMENT ;
- if (position >= MAX_POS ) {
- position = MAX_POS;
- rampUp = !rampUp; // Switch ramp direction
- }
- }
- else {
- // Keep stepping down until we hit the min value.
- position -= INCREMENT ;
- if (position <= MIN_POS ) {
- position = MIN_POS;
- rampUp = !rampUp; // Switch ramp direction
- }
- }
-
- // Display the current value
- telemetry.addData("Servo Position", "%5.2f", position);
- telemetry.addData(">", "Press Stop to end test." );
- telemetry.update();
-
- // Set the servo to the new position and pause;
- servo.setPosition(position);
- sleep(CYCLE_MS);
- idle();
- }
-
- // Signal done;
- telemetry.addData(">", "Done");
- telemetry.update();
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptSoundsASJava.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptSoundsASJava.java
deleted file mode 100644
index 1ceaa17d..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptSoundsASJava.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/* Copyright (c) 2018 FIRST. 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.ftccommon.SoundPlayer;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-
-/*
- * This OpMode demonstrates how to play simple sounds on both the RC and DS phones.
- * It illustrates how to build sounds into your application as a resource.
- * This technique is best suited for use with Android Studio since it assumes you will be creating a new application
- *
- * If you are using OnBotJava, please see the ConceptSoundsOnBotJava sample
- *
- * 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
- *
- * Operation:
- *
- * Gamepad X & B buttons are used to trigger sounds in this example, but any event can be used.
- * Note: Time should be allowed for sounds to complete before playing other sounds.
- *
- * For sound files to be used as a compiled-in resource, they need to be located in a folder called "raw" under your "res" (resources) folder.
- * You can create your own "raw" folder from scratch, or you can copy the one from the FtcRobotController module.
- *
- * Android Studio coders will ultimately need a folder in your path as follows:
- * /TeamCode/src/main/res/raw
- *
- * Copy any .wav files you want to play into this folder.
- * Make sure that your files ONLY use lower-case characters, and have no spaces or special characters other than underscore.
- *
- * The name you give your .wav files will become the resource ID for these sounds.
- * eg: gold.wav becomes R.raw.gold
- *
- * If you wish to use the sounds provided for this sample, they are located in:
- * /FtcRobotController/src/main/res/raw
- * You can copy and paste the entire 'raw' folder using Android Studio.
- *
- */
-
-@TeleOp(name="Concept: Sound Resources", group="Concept")
-@Disabled
-public class ConceptSoundsASJava extends LinearOpMode {
-
- // Declare OpMode members.
- private boolean goldFound; // Sound file present flags
- private boolean silverFound;
-
- private boolean isX = false; // Gamepad button state variables
- private boolean isB = false;
-
- private boolean wasX = false; // Gamepad button history variables
- private boolean WasB = false;
-
- @Override
- public void runOpMode() {
-
- // Determine Resource IDs for sounds built into the RC application.
- int silverSoundID = hardwareMap.appContext.getResources().getIdentifier("silver", "raw", hardwareMap.appContext.getPackageName());
- int goldSoundID = hardwareMap.appContext.getResources().getIdentifier("gold", "raw", hardwareMap.appContext.getPackageName());
-
- // Determine if sound resources are found.
- // Note: Preloading is NOT required, but it's a good way to verify all your sounds are available before you run.
- if (goldSoundID != 0)
- goldFound = SoundPlayer.getInstance().preload(hardwareMap.appContext, goldSoundID);
-
- if (silverSoundID != 0)
- silverFound = SoundPlayer.getInstance().preload(hardwareMap.appContext, silverSoundID);
-
- // Display sound status
- 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" );
-
- // Wait for the game to start (driver presses START)
- telemetry.addData(">", "Press Start to continue");
- telemetry.update();
- waitForStart();
-
- telemetry.addData(">", "Press X, B to play sounds.");
- telemetry.update();
-
- // run until the end of the match (driver presses STOP)
- while (opModeIsActive()) {
-
- // say Silver each time gamepad X is pressed (This sound is a resource)
- if (silverFound && (isX = gamepad1.x) && !wasX) {
- SoundPlayer.getInstance().startPlaying(hardwareMap.appContext, silverSoundID);
- telemetry.addData("Playing", "Resource Silver");
- telemetry.update();
- }
-
- // say Gold each time gamepad B is pressed (This sound is a resource)
- if (goldFound && (isB = gamepad1.b) && !WasB) {
- SoundPlayer.getInstance().startPlaying(hardwareMap.appContext, goldSoundID);
- telemetry.addData("Playing", "Resource Gold");
- telemetry.update();
- }
-
- // Save last button states
- wasX = isX;
- WasB = isB;
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptSoundsOnBotJava.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptSoundsOnBotJava.java
deleted file mode 100644
index fbb7416c..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptSoundsOnBotJava.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/* Copyright (c) 2018 FIRST. 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.ftccommon.SoundPlayer;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-
-import java.io.File;
-
-/*
- * This OpMode demonstrates how to play simple sounds on both the RC and DS phones.
- * It illustrates how to play sound files that have been copied to the RC Phone
- * This technique is best suited for use with OnBotJava since it does not require the app to be modified.
- *
- * Operation:
- *
- * Gamepad X & B buttons are used to trigger sounds in this example, but any event can be used.
- * Note: Time should be allowed for sounds to complete before playing other sounds.
- *
- * To play a new sound, you will need to copy the .wav files to the phone, and then provide the full path to them as part of your OpMode.
- * This is done in this sample for the two sound files. silver.wav and gold.wav
- *
- * You can put the files in a variety of soundPaths, but we recommend you put them in the /FIRST/blocks/sounds folder.
- * Your OpModes will have guaranteed access to this folder, and you can transfer files into this folder using the BLOCKS web page.
- * -- There is a link called "sounds" on the right hand side of the color bar on the BLOCKS page that can be used to send sound files to this folder by default.
- * Or you can use Windows File Manager, or ADB to transfer the sound files
- *
- * To get full use of THIS sample, you will need to copy two sound file called silver.wav and gold.wav to /FIRST/blocks/sounds on the RC phone.
- * They can be located here:
- * https://github.com/ftctechnh/ftc_app/tree/master/FtcRobotController/src/main/res/raw/gold.wav
- * https://github.com/ftctechnh/ftc_app/tree/master/FtcRobotController/src/main/res/raw/silver.wav
- */
-
-@TeleOp(name="Concept: Sound Files", group="Concept")
-@Disabled
-public class ConceptSoundsOnBotJava extends LinearOpMode {
-
- // Point to sound files on the phone's drive
- private String soundPath = "/FIRST/blocks/sounds";
- private File goldFile = new File("/sdcard" + soundPath + "/gold.wav");
- private File silverFile = new File("/sdcard" + soundPath + "/silver.wav");
-
- // Declare OpMode members.
- private boolean isX = false; // Gamepad button state variables
- private boolean isB = false;
-
- private boolean wasX = false; // Gamepad button history variables
- private boolean WasB = false;
-
- @Override
- public void runOpMode() {
-
- // Make sure that the sound files exist on the phone
- boolean goldFound = goldFile.exists();
- boolean silverFound = silverFile.exists();
-
- // Display sound status
- telemetry.addData("gold sound", goldFound ? "Found" : "NOT Found \nCopy gold.wav to " + soundPath );
- telemetry.addData("silver sound", silverFound ? "Found" : "NOT Found \nCopy silver.wav to " + soundPath );
-
- // Wait for the game to start (driver presses PLAY)
- telemetry.addData(">", "Press Start to continue");
- telemetry.update();
- waitForStart();
-
- telemetry.addData(">", "Press X or B to play sounds.");
- telemetry.update();
-
- // run until the end of the match (driver presses STOP)
- while (opModeIsActive()) {
-
- // say Silver each time gamepad X is pressed (This sound is a resource)
- if (silverFound && (isX = gamepad1.x) && !wasX) {
- SoundPlayer.getInstance().startPlaying(hardwareMap.appContext, silverFile);
- telemetry.addData("Playing", "Silver File");
- telemetry.update();
- }
-
- // say Gold each time gamepad B is pressed (This sound is a resource)
- if (goldFound && (isB = gamepad1.b) && !WasB) {
- SoundPlayer.getInstance().startPlaying(hardwareMap.appContext, goldFile);
- telemetry.addData("Playing", "Gold File");
- telemetry.update();
- }
-
- // Save last button states
- wasX = isX;
- WasB = isB;
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptSoundsSKYSTONE.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptSoundsSKYSTONE.java
deleted file mode 100644
index 983e434f..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptSoundsSKYSTONE.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/* Copyright (c) 2018 FIRST. 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 android.content.Context;
-import com.qualcomm.ftccommon.SoundPlayer;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-
-/*
- * This OpMode demonstrates how to play one of the several SKYSTONE/Star Wars sounds loaded into the SDK.
- * It does this by creating a simple "chooser" controlled by the gamepad Up Down buttons.
- * This code also prevents sounds from stacking up by setting a "playing" flag, which is cleared when the sound finishes playing.
- *
- * 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
- *
- * Operation:
- * Use the DPAD to change the selected sound, and the Right Bumper to play it.
- */
-
-@TeleOp(name="SKYSTONE Sounds", group="Concept")
-@Disabled
-public class ConceptSoundsSKYSTONE extends LinearOpMode {
-
- // List of available sound resources
- String sounds[] = {"ss_alarm", "ss_bb8_down", "ss_bb8_up", "ss_darth_vader", "ss_fly_by",
- "ss_mf_fail", "ss_laser", "ss_laser_burst", "ss_light_saber", "ss_light_saber_long", "ss_light_saber_short",
- "ss_light_speed", "ss_mine", "ss_power_up", "ss_r2d2_up", "ss_roger_roger", "ss_siren", "ss_wookie" };
- boolean soundPlaying = false;
-
- @Override
- public void runOpMode() {
-
- // Variables for choosing from the available sounds
- int soundIndex = 0;
- int soundID = -1;
- boolean was_dpad_up = false;
- boolean was_dpad_down = false;
-
- Context myApp = hardwareMap.appContext;
-
- // create a sound parameter that holds the desired player parameters.
- SoundPlayer.PlaySoundParams params = new SoundPlayer.PlaySoundParams();
- params.loopControl = 0;
- params.waitForNonLoopingSoundsToFinish = true;
-
- // In this sample, we will skip waiting for the user to press play, and start displaying sound choices right away
- while (!isStopRequested()) {
-
- // Look for DPAD presses to change the selection
- if (gamepad1.dpad_down && !was_dpad_down) {
- // Go to next sound (with list wrap) and display it
- soundIndex = (soundIndex + 1) % sounds.length;
- }
-
- if (gamepad1.dpad_up && !was_dpad_up) {
- // Go to previous sound (with list wrap) and display it
- soundIndex = (soundIndex + sounds.length - 1) % sounds.length;
- }
-
- // Look for trigger to see if we should play sound
- // Only start a new sound if we are currently not playing one.
- if (gamepad1.right_bumper && !soundPlaying) {
-
- // Determine Resource IDs for the sounds you want to play, and make sure it's valid.
- if ((soundID = myApp.getResources().getIdentifier(sounds[soundIndex], "raw", myApp.getPackageName())) != 0){
-
- // Signal that the sound is now playing.
- soundPlaying = true;
-
- // Start playing, and also Create a callback that will clear the playing flag when the sound is complete.
- SoundPlayer.getInstance().startPlaying(myApp, soundID, params, null,
- new Runnable() {
- public void run() {
- soundPlaying = false;
- }} );
- }
- }
-
- // Remember the last state of the dpad to detect changes.
- was_dpad_up = gamepad1.dpad_up;
- was_dpad_down = gamepad1.dpad_down;
-
- // Display the current sound choice, and the playing status.
- telemetry.addData("", "Use DPAD up/down to choose sound.");
- telemetry.addData("", "Press Right Bumper to play sound.");
- telemetry.addData("", "");
- telemetry.addData("Sound >", sounds[soundIndex]);
- telemetry.addData("Status >", soundPlaying ? "Playing" : "Stopped");
- telemetry.update();
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptTelemetry.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptTelemetry.java
deleted file mode 100644
index f2c60970..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptTelemetry.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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 com.qualcomm.robotcore.hardware.VoltageSensor;
-import com.qualcomm.robotcore.util.ElapsedTime;
-import org.firstinspires.ftc.robotcore.external.Func;
-import org.firstinspires.ftc.robotcore.external.Telemetry;
-
-/*
- * This OpMode illustrates various ways in which telemetry can be
- * transmitted from the robot controller to the driver station. The sample illustrates
- * numeric and text data, formatted output, and optimized evaluation of expensive-to-acquire
- * information. The telemetry log is illustrated by scrolling a poem
- * to the driver station.
- *
- * Also see the Telemetry javadocs.
- */
-@TeleOp(name = "Concept: Telemetry", group = "Concept")
-@Disabled
-public class ConceptTelemetry extends LinearOpMode {
- /** Keeps track of the line of the poem which is to be emitted next */
- int poemLine = 0;
-
- /** Keeps track of how long it's been since we last emitted a line of poetry */
- ElapsedTime poemElapsed = new ElapsedTime();
-
- static final String[] poem = new String[] {
-
- "Mary had a little lamb,",
- "His fleece was white as snow,",
- "And everywhere that Mary went,",
- "The lamb was sure to go.",
- "",
- "He followed her to school one day,",
- "Which was against the rule,",
- "It made the children laugh and play",
- "To see a lamb at school.",
- "",
- "And so the teacher turned it out,",
- "But still it lingered near,",
- "And waited patiently about,",
- "Till Mary did appear.",
- "",
- "\"Why does the lamb love Mary so?\"",
- "The eager children cry.",
- "\"Why, Mary loves the lamb, you know,\"",
- "The teacher did reply.",
- "",
- ""
- };
-
- @Override public void runOpMode() {
-
- /* we keep track of how long it's been since the OpMode was started, just
- * to have some interesting data to show */
- ElapsedTime opmodeRunTime = new ElapsedTime();
-
- // We show the log in oldest-to-newest order, as that's better for poetry
- telemetry.log().setDisplayOrder(Telemetry.Log.DisplayOrder.OLDEST_FIRST);
- // We can control the number of lines shown in the log
- telemetry.log().setCapacity(6);
- // The interval between lines of poetry, in seconds
- double sPoemInterval = 0.6;
-
- /*
- * Wait until we've been given the ok to go. For something to do, we emit the
- * elapsed time as we sit here and wait. If we didn't want to do anything while
- * we waited, we would just call waitForStart().
- */
- while (!isStarted()) {
- telemetry.addData("time", "%.1f seconds", opmodeRunTime.seconds());
- telemetry.update();
- idle();
- }
-
- // Ok, we've been given the ok to go
-
- /*
- * As an illustration, the first line on our telemetry display will display the battery voltage.
- * The idea here is that it's expensive to compute the voltage (at least for purposes of illustration)
- * so you don't want to do it unless the data is _actually_ going to make it to the
- * driver station (recall that telemetry transmission is throttled to reduce bandwidth use.
- * Note that getBatteryVoltage() below returns 'Infinity' if there's no voltage sensor attached.
- *
- * @see Telemetry#getMsTransmissionInterval()
- */
- telemetry.addData("voltage", "%.1f volts", new Func() {
- @Override public Double value() {
- return getBatteryVoltage();
- }
- });
-
- // Reset to keep some timing stats for the post-'start' part of the OpMode
- opmodeRunTime.reset();
- int loopCount = 1;
-
- // Go go gadget robot!
- while (opModeIsActive()) {
-
- // Emit poetry if it's been a while
- if (poemElapsed.seconds() > sPoemInterval) {
- emitPoemLine();
- }
-
- // As an illustration, show some loop timing information
- telemetry.addData("loop count", loopCount);
- telemetry.addData("ms/loop", "%.3f ms", opmodeRunTime.milliseconds() / loopCount);
-
- // Show joystick information as some other illustrative data
- telemetry.addLine("left joystick | ")
- .addData("x", gamepad1.left_stick_x)
- .addData("y", gamepad1.left_stick_y);
- telemetry.addLine("right joystick | ")
- .addData("x", gamepad1.right_stick_x)
- .addData("y", gamepad1.right_stick_y);
-
- /*
- * Transmit the telemetry to the driver station, subject to throttling.
- * See the documentation for Telemetry.getMsTransmissionInterval() for more information.
- */
- telemetry.update();
-
- // Update loop info
- loopCount++;
- }
- }
-
- // emits a line of poetry to the telemetry log
- void emitPoemLine() {
- telemetry.log().add(poem[poemLine]);
- poemLine = (poemLine+1) % poem.length;
- poemElapsed.reset();
- }
-
- // Computes the current battery voltage
- double getBatteryVoltage() {
- double result = Double.POSITIVE_INFINITY;
- for (VoltageSensor sensor : hardwareMap.voltageSensor) {
- double voltage = sensor.getVoltage();
- if (voltage > 0) {
- result = Math.min(result, voltage);
- }
- }
- return result;
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVisionColorLocator.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVisionColorLocator.java
deleted file mode 100644
index 987694db..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVisionColorLocator.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (c) 2024 Phil Malone
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.firstinspires.ftc.robotcontroller.external.samples;
-
-import android.util.Size;
-
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.util.SortOrder;
-
-import org.firstinspires.ftc.robotcore.external.Telemetry;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName;
-import org.firstinspires.ftc.vision.VisionPortal;
-import org.firstinspires.ftc.vision.opencv.ColorBlobLocatorProcessor;
-import org.firstinspires.ftc.vision.opencv.ColorRange;
-import org.firstinspires.ftc.vision.opencv.ImageRegion;
-import org.opencv.core.RotatedRect;
-
-import java.util.List;
-
-/*
- * This OpMode illustrates how to use a video source (camera) to locate specifically colored regions
- *
- * Unlike a "color sensor" which determines the color of an object in the field of view, this "color locator"
- * will search the Region Of Interest (ROI) in a camera image, and find any "blobs" of color that match the requested color range.
- * These blobs can be further filtered and sorted to find the one most likely to be the item the user is looking for.
- *
- * To perform this function, a VisionPortal runs a ColorBlobLocatorProcessor process.
- * The ColorBlobLocatorProcessor process is created first, and then the VisionPortal is built to use this process.
- * The ColorBlobLocatorProcessor analyses the ROI and locates pixels that match the ColorRange to form a "mask".
- * The matching pixels are then collected into contiguous "blobs" of pixels. The outer boundaries of these blobs are called its "contour".
- * For each blob, the process then creates the smallest possible rectangle "boxFit" that will fully encase the contour.
- * The user can then call getBlobs() to retrieve the list of Blobs, where each Blob contains the contour and the boxFit data.
- * Note: The default sort order for Blobs is ContourArea, in descending order, so the biggest contours are listed first.
- *
- * To aid the user, a colored boxFit rectangle is drawn on the camera preview to show the location of each Blob
- * The original Blob contour can also be added to the preview. This is helpful when configuring the ColorBlobLocatorProcessor parameters.
- *
- * 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
- */
-
-@Disabled
-@TeleOp(name = "Concept: Vision Color-Locator", group = "Concept")
-public class ConceptVisionColorLocator extends LinearOpMode
-{
- @Override
- public void runOpMode()
- {
- /* Build a "Color Locator" vision processor based on the ColorBlobLocatorProcessor class.
- * - Specify the color range you are looking for. You can use a predefined color, or create you own color range
- * .setTargetColorRange(ColorRange.BLUE) // use a predefined color match
- * Available predefined colors are: RED, BLUE YELLOW GREEN
- * .setTargetColorRange(new ColorRange(ColorSpace.YCrCb, // or define your own color match
- * new Scalar( 32, 176, 0),
- * new Scalar(255, 255, 132)))
- *
- * - Focus the color locator by defining a RegionOfInterest (ROI) which you want to search.
- * This can be the entire frame, or a sub-region defined using:
- * 1) standard image coordinates or 2) a normalized +/- 1.0 coordinate system.
- * Use one form of the ImageRegion class to define the ROI.
- * ImageRegion.entireFrame()
- * ImageRegion.asImageCoordinates(50, 50, 150, 150) 100x100 pixel square near the upper left corner
- * ImageRegion.asUnityCenterCoordinates(-0.5, 0.5, 0.5, -0.5) 50% width/height square centered on screen
- *
- * - Define which contours are included.
- * You can get ALL the contours, or you can skip any contours that are completely inside another contour.
- * .setContourMode(ColorBlobLocatorProcessor.ContourMode.ALL_FLATTENED_HIERARCHY) // return all contours
- * .setContourMode(ColorBlobLocatorProcessor.ContourMode.EXTERNAL_ONLY) // exclude contours inside other contours
- * note: EXTERNAL_ONLY helps to avoid bright reflection spots from breaking up areas of solid color.
- *
- * - turn the display of contours ON or OFF. Turning this on helps debugging but takes up valuable CPU time.
- * .setDrawContours(true)
- *
- * - include any pre-processing of the image or mask before looking for Blobs.
- * There are some extra processing you can include to improve the formation of blobs. Using these features requires
- * an understanding of how they may effect the final blobs. The "pixels" argument sets the NxN kernel size.
- * .setBlurSize(int pixels) Blurring an image helps to provide a smooth color transition between objects, and smoother contours.
- * The higher the number of pixels, the more blurred the image becomes.
- * Note: Even "pixels" values will be incremented to satisfy the "odd number" requirement.
- * Blurring too much may hide smaller features. A "pixels" size of 5 is good for a 320x240 image.
- * .setErodeSize(int pixels) Erosion removes floating pixels and thin lines so that only substantive objects remain.
- * Erosion can grow holes inside regions, and also shrink objects.
- * "pixels" in the range of 2-4 are suitable for low res images.
- * .setDilateSize(int pixels) Dilation makes objects more visible by filling in small holes, making lines appear thicker,
- * and making filled shapes appear larger. Dilation is useful for joining broken parts of an
- * object, such as when removing noise from an image.
- * "pixels" in the range of 2-4 are suitable for low res images.
- */
- ColorBlobLocatorProcessor colorLocator = new ColorBlobLocatorProcessor.Builder()
- .setTargetColorRange(ColorRange.BLUE) // use a predefined color match
- .setContourMode(ColorBlobLocatorProcessor.ContourMode.EXTERNAL_ONLY) // exclude blobs inside blobs
- .setRoi(ImageRegion.asUnityCenterCoordinates(-0.5, 0.5, 0.5, -0.5)) // search central 1/4 of camera view
- .setDrawContours(true) // Show contours on the Stream Preview
- .setBlurSize(5) // Smooth the transitions between different colors in image
- .build();
-
- /*
- * Build a vision portal to run the Color Locator process.
- *
- * - Add the colorLocator process created above.
- * - Set the desired video resolution.
- * Since a high resolution will not improve this process, choose a lower resolution that is
- * supported by your camera. This will improve overall performance and reduce latency.
- * - Choose your video source. This may be
- * .setCamera(hardwareMap.get(WebcamName.class, "Webcam 1")) ..... for a webcam
- * or
- * .setCamera(BuiltinCameraDirection.BACK) ... for a Phone Camera
- */
- VisionPortal portal = new VisionPortal.Builder()
- .addProcessor(colorLocator)
- .setCameraResolution(new Size(320, 240))
- .setCamera(hardwareMap.get(WebcamName.class, "Webcam 1"))
- .build();
-
- telemetry.setMsTransmissionInterval(50); // Speed up telemetry updates, Just use for debugging.
- telemetry.setDisplayFormat(Telemetry.DisplayFormat.MONOSPACE);
-
- // WARNING: To be able to view the stream preview on the Driver Station, this code runs in INIT mode.
- while (opModeIsActive() || opModeInInit())
- {
- telemetry.addData("preview on/off", "... Camera Stream\n");
-
- // Read the current list
- List blobs = colorLocator.getBlobs();
-
- /*
- * The list of Blobs can be filtered to remove unwanted Blobs.
- * Note: All contours will be still displayed on the Stream Preview, but only those that satisfy the filter
- * conditions will remain in the current list of "blobs". Multiple filters may be used.
- *
- * Use any of the following filters.
- *
- * ColorBlobLocatorProcessor.Util.filterByArea(minArea, maxArea, blobs);
- * A Blob's area is the number of pixels contained within the Contour. Filter out any that are too big or small.
- * Start with a large range and then refine the range based on the likely size of the desired object in the viewfinder.
- *
- * ColorBlobLocatorProcessor.Util.filterByDensity(minDensity, maxDensity, blobs);
- * A blob's density is an indication of how "full" the contour is.
- * If you put a rubber band around the contour you would get the "Convex Hull" of the contour.
- * The density is the ratio of Contour-area to Convex Hull-area.
- *
- * ColorBlobLocatorProcessor.Util.filterByAspectRatio(minAspect, maxAspect, blobs);
- * A blob's Aspect ratio is the ratio of boxFit long side to short side.
- * A perfect Square has an aspect ratio of 1. All others are > 1
- */
- ColorBlobLocatorProcessor.Util.filterByArea(50, 20000, blobs); // filter out very small blobs.
-
- /*
- * The list of Blobs can be sorted using the same Blob attributes as listed above.
- * No more than one sort call should be made. Sorting can use ascending or descending order.
- * ColorBlobLocatorProcessor.Util.sortByArea(SortOrder.DESCENDING, blobs); // Default
- * ColorBlobLocatorProcessor.Util.sortByDensity(SortOrder.DESCENDING, blobs);
- * ColorBlobLocatorProcessor.Util.sortByAspectRatio(SortOrder.DESCENDING, blobs);
- */
-
- telemetry.addLine(" Area Density Aspect Center");
-
- // Display the size (area) and center location for each Blob.
- for(ColorBlobLocatorProcessor.Blob b : blobs)
- {
- RotatedRect boxFit = b.getBoxFit();
- telemetry.addLine(String.format("%5d %4.2f %5.2f (%3d,%3d)",
- b.getContourArea(), b.getDensity(), b.getAspectRatio(), (int) boxFit.center.x, (int) boxFit.center.y));
- }
-
- telemetry.update();
- sleep(50);
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVisionColorSensor.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVisionColorSensor.java
deleted file mode 100644
index 6be2bc4e..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVisionColorSensor.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (c) 2024 Phil Malone
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.firstinspires.ftc.robotcontroller.external.samples;
-
-import android.graphics.Color;
-import android.util.Size;
-
-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.WebcamName;
-import org.firstinspires.ftc.vision.VisionPortal;
-import org.firstinspires.ftc.vision.opencv.ImageRegion;
-import org.firstinspires.ftc.vision.opencv.PredominantColorProcessor;
-
-/*
- * This OpMode illustrates how to use a video source (camera) as a color sensor
- *
- * A "color sensor" will typically determine the color of the object that it is pointed at.
- *
- * This sample performs the same function, except it uses a video camera to inspect an object or scene.
- * The user may choose to inspect all, or just a Region of Interest (ROI), of the active camera view.
- * The user must also provide a list of "acceptable colors" (Swatches) from which the closest matching color will be selected.
- *
- * To perform this function, a VisionPortal runs a PredominantColorProcessor process.
- * The PredominantColorProcessor process is created first, and then the VisionPortal is built to use this process.
- * The PredominantColorProcessor analyses the ROI and splits the colored pixels into several color-clusters.
- * The largest of these clusters is then considered to be the "Predominant Color"
- * The process then matches the Predominant Color with the closest Swatch and returns that match.
- *
- * To aid the user, a colored rectangle is drawn on the camera preview to show the RegionOfInterest,
- * The Predominant Color is used to paint the rectangle border, so the user can verify that the color is reasonable.
- *
- * 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
- */
-
-@Disabled
-@TeleOp(name = "Concept: Vision Color-Sensor", group = "Concept")
-public class ConceptVisionColorSensor extends LinearOpMode
-{
- @Override
- public void runOpMode()
- {
- /* Build a "Color Sensor" vision processor based on the PredominantColorProcessor class.
- *
- * - Focus the color sensor by defining a RegionOfInterest (ROI) which you want to inspect.
- * This can be the entire frame, or a sub-region defined using:
- * 1) standard image coordinates or 2) a normalized +/- 1.0 coordinate system.
- * Use one form of the ImageRegion class to define the ROI.
- * ImageRegion.entireFrame()
- * ImageRegion.asImageCoordinates(50, 50, 150, 150) 100x100 pixel square near the upper left corner
- * ImageRegion.asUnityCenterCoordinates(-0.1, 0.1, 0.1, -0.1) 10% width/height square centered on screen
- *
- * - Set the list of "acceptable" color swatches (matches).
- * Only colors that you assign here will be returned.
- * If you know the sensor will be pointing to one of a few specific colors, enter them here.
- * Or, if the sensor may be pointed randomly, provide some additional colors that may match the surrounding.
- * Possible choices are:
- * RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, PURPLE, MAGENTA, BLACK, WHITE;
- *
- * Note that in the example shown below, only some of the available colors are included.
- * This will force any other colored region into one of these colors.
- * eg: Green may be reported as YELLOW, as this may be the "closest" match.
- */
- PredominantColorProcessor colorSensor = new PredominantColorProcessor.Builder()
- .setRoi(ImageRegion.asUnityCenterCoordinates(-0.1, 0.1, 0.1, -0.1))
- .setSwatches(
- PredominantColorProcessor.Swatch.RED,
- PredominantColorProcessor.Swatch.BLUE,
- PredominantColorProcessor.Swatch.YELLOW,
- PredominantColorProcessor.Swatch.BLACK,
- PredominantColorProcessor.Swatch.WHITE)
- .build();
-
- /*
- * Build a vision portal to run the Color Sensor process.
- *
- * - Add the colorSensor process created above.
- * - Set the desired video resolution.
- * Since a high resolution will not improve this process, choose a lower resolution that is
- * supported by your camera. This will improve overall performance and reduce latency.
- * - Choose your video source. This may be
- * .setCamera(hardwareMap.get(WebcamName.class, "Webcam 1")) ..... for a webcam
- * or
- * .setCamera(BuiltinCameraDirection.BACK) ... for a Phone Camera
- */
- VisionPortal portal = new VisionPortal.Builder()
- .addProcessor(colorSensor)
- .setCameraResolution(new Size(320, 240))
- .setCamera(hardwareMap.get(WebcamName.class, "Webcam 1"))
- .build();
-
- telemetry.setMsTransmissionInterval(50); // Speed up telemetry updates, Just use for debugging.
-
- // WARNING: To be able to view the stream preview on the Driver Station, this code runs in INIT mode.
- while (opModeIsActive() || opModeInInit())
- {
- telemetry.addData("DS preview on/off", "3 dots, Camera Stream\n");
-
- // Request the most recent color analysis.
- // This will return the closest matching colorSwatch and the predominant RGB color.
- // Note: to take actions based on the detected color, simply use the colorSwatch in a comparison or switch.
- // eg:
- // if (result.closestSwatch == PredominantColorProcessor.Swatch.RED) {... some code ...}
- PredominantColorProcessor.Result result = colorSensor.getAnalysis();
-
- // Display the Color Sensor result.
- telemetry.addData("Best Match:", result.closestSwatch);
- telemetry.addLine(String.format("R %3d, G %3d, B %3d", Color.red(result.rgb), Color.green(result.rgb), Color.blue(result.rgb)));
- telemetry.update();
-
- sleep(20);
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveByEncoder_Linear.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveByEncoder_Linear.java
deleted file mode 100644
index 63293d0c..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveByEncoder_Linear.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.Autonomous;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.util.ElapsedTime;
-
-/*
- * This OpMode illustrates the concept of driving a path based on encoder counts.
- * The code is structured as a LinearOpMode
- *
- * The code REQUIRES that you DO have encoders on the wheels,
- * otherwise you would use: RobotAutoDriveByTime;
- *
- * This code ALSO requires that the drive Motors have been configured such that a positive
- * power command moves them forward, and causes the encoders to count UP.
- *
- * The desired path in this example is:
- * - Drive forward for 48 inches
- * - Spin right for 12 Inches
- * - Drive Backward for 24 inches
- * - Stop and close the claw.
- *
- * The code is written using a method called: encoderDrive(speed, leftInches, rightInches, timeoutS)
- * that performs the actual movement.
- * This method assumes that each movement is relative to the last stopping place.
- * There are other ways to perform encoder based moves, but this method is probably the simplest.
- * This code uses the RUN_TO_POSITION mode to enable the Motor controllers to generate the run profile
- *
- * 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
- */
-
-@Autonomous(name="Robot: Auto Drive By Encoder", group="Robot")
-@Disabled
-public class RobotAutoDriveByEncoder_Linear extends LinearOpMode {
-
- /* Declare OpMode members. */
- private DcMotor leftDrive = null;
- private DcMotor rightDrive = null;
-
- private ElapsedTime runtime = new ElapsedTime();
-
- // Calculate the COUNTS_PER_INCH for your specific drive train.
- // Go to your motor vendor website to determine your motor's COUNTS_PER_MOTOR_REV
- // For external drive gearing, set DRIVE_GEAR_REDUCTION as needed.
- // For example, use a value of 2.0 for a 12-tooth spur gear driving a 24-tooth spur gear.
- // This is gearing DOWN for less speed and more torque.
- // For gearing UP, use a gear ratio less than 1.0. Note this will affect the direction of wheel rotation.
- static final double COUNTS_PER_MOTOR_REV = 1440 ; // eg: TETRIX Motor Encoder
- static final double DRIVE_GEAR_REDUCTION = 1.0 ; // No External Gearing.
- static final double WHEEL_DIAMETER_INCHES = 4.0 ; // For figuring circumference
- static final double COUNTS_PER_INCH = (COUNTS_PER_MOTOR_REV * DRIVE_GEAR_REDUCTION) /
- (WHEEL_DIAMETER_INCHES * 3.1415);
- static final double DRIVE_SPEED = 0.6;
- static final double TURN_SPEED = 0.5;
-
- @Override
- public void runOpMode() {
-
- // Initialize the drive system variables.
- leftDrive = hardwareMap.get(DcMotor.class, "left_drive");
- rightDrive = hardwareMap.get(DcMotor.class, "right_drive");
-
- // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
- // When run, this OpMode should start both motors driving forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Gear Reduction or 90 Deg drives may require direction flips
- leftDrive.setDirection(DcMotor.Direction.REVERSE);
- rightDrive.setDirection(DcMotor.Direction.FORWARD);
-
- leftDrive.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
- rightDrive.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
-
- leftDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- rightDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
-
- // Send telemetry message to indicate successful Encoder reset
- telemetry.addData("Starting at", "%7d :%7d",
- leftDrive.getCurrentPosition(),
- rightDrive.getCurrentPosition());
- telemetry.update();
-
- // Wait for the game to start (driver presses START)
- waitForStart();
-
- // Step through each leg of the path,
- // Note: Reverse movement is obtained by setting a negative distance (not speed)
- encoderDrive(DRIVE_SPEED, 48, 48, 5.0); // S1: Forward 47 Inches with 5 Sec timeout
- encoderDrive(TURN_SPEED, 12, -12, 4.0); // S2: Turn Right 12 Inches with 4 Sec timeout
- encoderDrive(DRIVE_SPEED, -24, -24, 4.0); // S3: Reverse 24 Inches with 4 Sec timeout
-
- telemetry.addData("Path", "Complete");
- telemetry.update();
- sleep(1000); // pause to display final telemetry message.
- }
-
- /*
- * Method to perform a relative move, based on encoder counts.
- * Encoders are not reset as the move is based on the current position.
- * Move will stop if any of three conditions occur:
- * 1) Move gets to the desired position
- * 2) Move runs out of time
- * 3) Driver stops the OpMode running.
- */
- public void encoderDrive(double speed,
- double leftInches, double rightInches,
- double timeoutS) {
- int newLeftTarget;
- int newRightTarget;
-
- // Ensure that the OpMode is still active
- if (opModeIsActive()) {
-
- // Determine new target position, and pass to motor controller
- newLeftTarget = leftDrive.getCurrentPosition() + (int)(leftInches * COUNTS_PER_INCH);
- newRightTarget = rightDrive.getCurrentPosition() + (int)(rightInches * COUNTS_PER_INCH);
- leftDrive.setTargetPosition(newLeftTarget);
- rightDrive.setTargetPosition(newRightTarget);
-
- // Turn On RUN_TO_POSITION
- leftDrive.setMode(DcMotor.RunMode.RUN_TO_POSITION);
- rightDrive.setMode(DcMotor.RunMode.RUN_TO_POSITION);
-
- // reset the timeout time and start motion.
- runtime.reset();
- leftDrive.setPower(Math.abs(speed));
- rightDrive.setPower(Math.abs(speed));
-
- // keep looping while we are still active, and there is time left, and both motors are running.
- // Note: We use (isBusy() && isBusy()) in the loop test, which means that when EITHER motor hits
- // its target position, the motion will stop. This is "safer" in the event that the robot will
- // always end the motion as soon as possible.
- // However, if you require that BOTH motors have finished their moves before the robot continues
- // onto the next step, use (isBusy() || isBusy()) in the loop test.
- while (opModeIsActive() &&
- (runtime.seconds() < timeoutS) &&
- (leftDrive.isBusy() && rightDrive.isBusy())) {
-
- // Display it for the driver.
- telemetry.addData("Running to", " %7d :%7d", newLeftTarget, newRightTarget);
- telemetry.addData("Currently at", " at %7d :%7d",
- leftDrive.getCurrentPosition(), rightDrive.getCurrentPosition());
- telemetry.update();
- }
-
- // Stop all motion;
- leftDrive.setPower(0);
- rightDrive.setPower(0);
-
- // Turn off RUN_TO_POSITION
- leftDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- rightDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
-
- sleep(250); // optional pause after each move.
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveByGyro_Linear.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveByGyro_Linear.java
deleted file mode 100644
index ab709344..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveByGyro_Linear.java
+++ /dev/null
@@ -1,429 +0,0 @@
-/* Copyright (c) 2022 FIRST. 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.rev.RevHubOrientationOnRobot;
-import com.qualcomm.robotcore.eventloop.opmode.Autonomous;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.hardware.IMU;
-import com.qualcomm.robotcore.util.ElapsedTime;
-import com.qualcomm.robotcore.util.Range;
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-import org.firstinspires.ftc.robotcore.external.navigation.YawPitchRollAngles;
-
-/*
- * This OpMode illustrates the concept of driving an autonomous path based on Gyro (IMU) heading and encoder counts.
- * The code is structured as a LinearOpMode
- *
- * The path to be followed by the robot is built from a series of drive, turn or pause steps.
- * Each step on the path is defined by a single function call, and these can be strung together in any order.
- *
- * The code REQUIRES that you have encoders on the drive motors, otherwise you should use: RobotAutoDriveByTime;
- *
- * This code uses the Universal IMU interface so it will work with either the BNO055, or BHI260 IMU.
- * To run as written, the Control/Expansion hub should be mounted horizontally on a flat part of the robot chassis.
- * The REV Logo should be facing UP, and the USB port should be facing forward.
- * If this is not the configuration of your REV Control Hub, then the code should be modified to reflect the correct orientation.
- *
- * This sample requires that the drive Motors have been configured with names : left_drive and right_drive.
- * It also requires that a positive power command moves both motors forward, and causes the encoders to count UP.
- * So please verify that both of your motors move the robot forward on the first move. If not, make the required correction.
- * See the beginning of runOpMode() to set the FORWARD/REVERSE option for each motor.
- *
- * This code uses RUN_TO_POSITION mode for driving straight, and RUN_USING_ENCODER mode for turning and holding.
- * Note: This code implements the requirement of calling setTargetPosition() at least once before switching to RUN_TO_POSITION mode.
- *
- * Notes:
- *
- * 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.
- * 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,
- * which means that a Positive rotation is Counter Clockwise, looking down on the field.
- * This is consistent with the FTC field coordinate conventions set out in the document:
- * https://ftc-docs.firstinspires.org/field-coordinate-system
- *
- * Control Approach.
- *
- * To reach, or maintain a required heading, this code implements a basic Proportional Controller where:
- *
- * Steering power = Heading Error * Proportional Gain.
- *
- * "Heading Error" is calculated by taking the difference between the desired heading and the actual heading,
- * and then "normalizing" it by converting it to a value in the +/- 180 degree range.
- *
- * "Proportional Gain" is a constant that YOU choose to set the "strength" of the steering response.
- *
- * Use Android Studio to Copy this Class, and Paste it into your "TeamCode" folder with a new name.
- * Remove or comment out the @Disabled line to add this OpMode to the Driver Station OpMode list
- */
-
-@Autonomous(name="Robot: Auto Drive By Gyro", group="Robot")
-@Disabled
-public class RobotAutoDriveByGyro_Linear extends LinearOpMode {
-
- /* Declare OpMode members. */
- private DcMotor leftDrive = null;
- private DcMotor rightDrive = null;
- private IMU imu = null; // Control/Expansion Hub IMU
-
- private double headingError = 0;
-
- // These variable are declared here (as class members) so they can be updated in various methods,
- // but still be displayed by sendTelemetry()
- private double targetHeading = 0;
- private double driveSpeed = 0;
- private double turnSpeed = 0;
- private double leftSpeed = 0;
- private double rightSpeed = 0;
- private int leftTarget = 0;
- private int rightTarget = 0;
-
- // Calculate the COUNTS_PER_INCH for your specific drive train.
- // Go to your motor vendor website to determine your motor's COUNTS_PER_MOTOR_REV
- // For external drive gearing, set DRIVE_GEAR_REDUCTION as needed.
- // For example, use a value of 2.0 for a 12-tooth spur gear driving a 24-tooth spur gear.
- // This is gearing DOWN for less speed and more torque.
- // For gearing UP, use a gear ratio less than 1.0. Note this will affect the direction of wheel rotation.
- static final double COUNTS_PER_MOTOR_REV = 537.7 ; // eg: GoBILDA 312 RPM Yellow Jacket
- static final double DRIVE_GEAR_REDUCTION = 1.0 ; // No External Gearing.
- static final double WHEEL_DIAMETER_INCHES = 4.0 ; // For figuring circumference
- static final double COUNTS_PER_INCH = (COUNTS_PER_MOTOR_REV * DRIVE_GEAR_REDUCTION) /
- (WHEEL_DIAMETER_INCHES * 3.1415);
-
- // These constants define the desired driving/control characteristics
- // 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 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.
- // 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".
- // 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 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)
- 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.
-
-
- @Override
- public void runOpMode() {
-
- // Initialize the drive system variables.
- leftDrive = hardwareMap.get(DcMotor.class, "left_drive");
- rightDrive = hardwareMap.get(DcMotor.class, "right_drive");
-
- // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
- // When run, this OpMode should start both motors driving forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Gear Reduction or 90 Deg drives may require direction flips
- leftDrive.setDirection(DcMotor.Direction.REVERSE);
- rightDrive.setDirection(DcMotor.Direction.FORWARD);
-
- /* The next two lines define Hub orientation.
- * The Default Orientation (shown) is when a hub is mounted horizontally with the printed logo pointing UP and the USB port pointing FORWARD.
- *
- * To Do: EDIT these two lines to match YOUR mounting configuration.
- */
- RevHubOrientationOnRobot.LogoFacingDirection logoDirection = RevHubOrientationOnRobot.LogoFacingDirection.UP;
- RevHubOrientationOnRobot.UsbFacingDirection usbDirection = RevHubOrientationOnRobot.UsbFacingDirection.FORWARD;
- RevHubOrientationOnRobot orientationOnRobot = new RevHubOrientationOnRobot(logoDirection, usbDirection);
-
- // Now initialize the IMU with this mounting orientation
- // This sample expects the IMU to be in a REV Hub and named "imu".
- imu = hardwareMap.get(IMU.class, "imu");
- imu.initialize(new IMU.Parameters(orientationOnRobot));
-
- // Ensure the robot is stationary. Reset the encoders and set the motors to BRAKE mode
- leftDrive.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
- rightDrive.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
- leftDrive.setZeroPowerBehavior(DcMotor.ZeroPowerBehavior.BRAKE);
- rightDrive.setZeroPowerBehavior(DcMotor.ZeroPowerBehavior.BRAKE);
-
- // Wait for the game to start (Display Gyro value while waiting)
- while (opModeInInit()) {
- telemetry.addData(">", "Robot Heading = %4.0f", getHeading());
- telemetry.update();
- }
-
- // Set the encoders for closed loop speed control, and reset the heading.
- leftDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- rightDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- imu.resetYaw();
-
- // Step through each leg of the path,
- // Notes: Reverse movement is obtained by setting a negative distance (not speed)
- // holdHeading() is used after turns to let the heading stabilize
- // Add a sleep(2000) after any step to keep the telemetry data visible for review
-
- driveStraight(DRIVE_SPEED, 24.0, 0.0); // Drive Forward 24"
- turnToHeading( TURN_SPEED, -45.0); // Turn CW to -45 Degrees
- holdHeading( TURN_SPEED, -45.0, 0.5); // Hold -45 Deg heading for a 1/2 second
-
- driveStraight(DRIVE_SPEED, 17.0, -45.0); // Drive Forward 17" at -45 degrees (12"x and 12"y)
- turnToHeading( TURN_SPEED, 45.0); // Turn CCW to 45 Degrees
- holdHeading( TURN_SPEED, 45.0, 0.5); // Hold 45 Deg heading for a 1/2 second
-
- driveStraight(DRIVE_SPEED, 17.0, 45.0); // Drive Forward 17" at 45 degrees (-12"x and 12"y)
- turnToHeading( TURN_SPEED, 0.0); // Turn CW to 0 Degrees
- holdHeading( TURN_SPEED, 0.0, 1.0); // Hold 0 Deg heading for 1 second
-
- driveStraight(DRIVE_SPEED,-48.0, 0.0); // Drive in Reverse 48" (should return to approx. staring position)
-
- telemetry.addData("Path", "Complete");
- telemetry.update();
- sleep(1000); // Pause to display last telemetry message.
- }
-
- /*
- * ====================================================================================================
- * Driving "Helper" functions are below this line.
- * These provide the high and low level methods that handle driving straight and turning.
- * ====================================================================================================
- */
-
- // ********** HIGH Level driving functions. ********************
-
- /**
- * Drive in a straight line, on a fixed compass heading (angle), based on encoder counts.
- * Move will stop if either of these conditions occur:
- * 1) Move gets to the desired position
- * 2) Driver stops the OpMode running.
- *
- * @param maxDriveSpeed MAX Speed for forward/rev motion (range 0 to +1.0) .
- * @param distance Distance (in inches) to move from current position. Negative distance means move backward.
- * @param heading Absolute Heading Angle (in Degrees) relative to last gyro reset.
- * 0 = fwd. +ve is CCW from fwd. -ve is CW from forward.
- * If a relative angle is required, add/subtract from the current robotHeading.
- */
- public void driveStraight(double maxDriveSpeed,
- double distance,
- double heading) {
-
- // Ensure that the OpMode is still active
- if (opModeIsActive()) {
-
- // Determine new target position, and pass to motor controller
- int moveCounts = (int)(distance * COUNTS_PER_INCH);
- leftTarget = leftDrive.getCurrentPosition() + moveCounts;
- rightTarget = rightDrive.getCurrentPosition() + moveCounts;
-
- // Set Target FIRST, then turn on RUN_TO_POSITION
- leftDrive.setTargetPosition(leftTarget);
- rightDrive.setTargetPosition(rightTarget);
-
- leftDrive.setMode(DcMotor.RunMode.RUN_TO_POSITION);
- rightDrive.setMode(DcMotor.RunMode.RUN_TO_POSITION);
-
- // Set the required driving speed (must be positive for RUN_TO_POSITION)
- // Start driving straight, and then enter the control loop
- maxDriveSpeed = Math.abs(maxDriveSpeed);
- moveRobot(maxDriveSpeed, 0);
-
- // keep looping while we are still active, and BOTH motors are running.
- while (opModeIsActive() &&
- (leftDrive.isBusy() && rightDrive.isBusy())) {
-
- // Determine required steering to keep on heading
- turnSpeed = getSteeringCorrection(heading, P_DRIVE_GAIN);
-
- // if driving in reverse, the motor correction also needs to be reversed
- if (distance < 0)
- turnSpeed *= -1.0;
-
- // Apply the turning correction to the current driving speed.
- moveRobot(driveSpeed, turnSpeed);
-
- // Display drive status for the driver.
- sendTelemetry(true);
- }
-
- // Stop all motion & Turn off RUN_TO_POSITION
- moveRobot(0, 0);
- leftDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- rightDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- }
- }
-
- /**
- * Spin on the central axis to point in a new direction.
- *
- * Move will stop if either of these conditions occur:
- *
- * 1) Move gets to the heading (angle)
- *
- * 2) Driver stops the OpMode running.
- *
- * @param maxTurnSpeed Desired MAX speed of turn. (range 0 to +1.0)
- * @param heading Absolute Heading Angle (in Degrees) relative to last gyro reset.
- * 0 = fwd. +ve is CCW from fwd. -ve is CW from forward.
- * If a relative angle is required, add/subtract from current heading.
- */
- public void turnToHeading(double maxTurnSpeed, double heading) {
-
- // Run getSteeringCorrection() once to pre-calculate the current error
- getSteeringCorrection(heading, P_DRIVE_GAIN);
-
- // keep looping while we are still active, and not on heading.
- while (opModeIsActive() && (Math.abs(headingError) > HEADING_THRESHOLD)) {
-
- // Determine required steering to keep on heading
- turnSpeed = getSteeringCorrection(heading, P_TURN_GAIN);
-
- // Clip the speed to the maximum permitted value.
- turnSpeed = Range.clip(turnSpeed, -maxTurnSpeed, maxTurnSpeed);
-
- // Pivot in place by applying the turning correction
- moveRobot(0, turnSpeed);
-
- // Display drive status for the driver.
- sendTelemetry(false);
- }
-
- // Stop all motion;
- moveRobot(0, 0);
- }
-
- /**
- * Obtain & hold a heading for a finite amount of time
- *
- * Move will stop once the requested time has elapsed
- *
- * 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 heading Absolute Heading Angle (in Degrees) relative to last gyro reset.
- * 0 = fwd. +ve is CCW from fwd. -ve is CW from forward.
- * If a relative angle is required, add/subtract from current heading.
- * @param holdTime Length of time (in seconds) to hold the specified heading.
- */
- public void holdHeading(double maxTurnSpeed, double heading, double holdTime) {
-
- ElapsedTime holdTimer = new ElapsedTime();
- holdTimer.reset();
-
- // keep looping while we have time remaining.
- while (opModeIsActive() && (holdTimer.time() < holdTime)) {
- // Determine required steering to keep on heading
- turnSpeed = getSteeringCorrection(heading, P_TURN_GAIN);
-
- // Clip the speed to the maximum permitted value.
- turnSpeed = Range.clip(turnSpeed, -maxTurnSpeed, maxTurnSpeed);
-
- // Pivot in place by applying the turning correction
- moveRobot(0, turnSpeed);
-
- // Display drive status for the driver.
- sendTelemetry(false);
- }
-
- // Stop all motion;
- moveRobot(0, 0);
- }
-
- // ********** LOW Level driving functions. ********************
-
- /**
- * Use a Proportional Controller to determine how much steering correction is required.
- *
- * @param desiredHeading The desired absolute heading (relative to last heading reset)
- * @param proportionalGain Gain factor applied to heading error to obtain turning power.
- * @return Turning power needed to get to required heading.
- */
- public double getSteeringCorrection(double desiredHeading, double proportionalGain) {
- targetHeading = desiredHeading; // Save for telemetry
-
- // Determine the heading current error
- headingError = targetHeading - getHeading();
-
- // Normalize the error to be within +/- 180 degrees
- while (headingError > 180) headingError -= 360;
- while (headingError <= -180) headingError += 360;
-
- // Multiply the error by the gain to determine the required steering correction/ Limit the result to +/- 1.0
- return Range.clip(headingError * proportionalGain, -1, 1);
- }
-
- /**
- * Take separate drive (fwd/rev) and turn (right/left) requests,
- * combines them, and applies the appropriate speed commands to the left and right wheel motors.
- * @param drive forward motor speed
- * @param turn clockwise turning motor speed.
- */
- public void moveRobot(double drive, double turn) {
- driveSpeed = drive; // save this value as a class member so it can be used by telemetry.
- turnSpeed = turn; // save this value as a class member so it can be used by telemetry.
-
- leftSpeed = drive - turn;
- rightSpeed = drive + turn;
-
- // Scale speeds down if either one exceeds +/- 1.0;
- double max = Math.max(Math.abs(leftSpeed), Math.abs(rightSpeed));
- if (max > 1.0)
- {
- leftSpeed /= max;
- rightSpeed /= max;
- }
-
- leftDrive.setPower(leftSpeed);
- rightDrive.setPower(rightSpeed);
- }
-
- /**
- * Display the various control parameters while driving
- *
- * @param straight Set to true if we are driving straight, and the encoder positions should be included in the telemetry.
- */
- private void sendTelemetry(boolean straight) {
-
- if (straight) {
- telemetry.addData("Motion", "Drive Straight");
- telemetry.addData("Target Pos L:R", "%7d:%7d", leftTarget, rightTarget);
- telemetry.addData("Actual Pos L:R", "%7d:%7d", leftDrive.getCurrentPosition(),
- rightDrive.getCurrentPosition());
- } else {
- telemetry.addData("Motion", "Turning");
- }
-
- telemetry.addData("Heading- Target : Current", "%5.2f : %5.0f", targetHeading, getHeading());
- telemetry.addData("Error : Steer Pwr", "%5.1f : %5.1f", headingError, turnSpeed);
- telemetry.addData("Wheel Speeds L : R", "%5.2f : %5.2f", leftSpeed, rightSpeed);
- telemetry.update();
- }
-
- /**
- * read the Robot heading directly from the IMU (in degrees)
- */
- public double getHeading() {
- YawPitchRollAngles orientation = imu.getRobotYawPitchRollAngles();
- return orientation.getYaw(AngleUnit.DEGREES);
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveByTime_Linear.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveByTime_Linear.java
deleted file mode 100644
index a7147481..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveByTime_Linear.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.Autonomous;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.util.ElapsedTime;
-
-/*
- * This OpMode illustrates the concept of driving a path based on time.
- * The code is structured as a LinearOpMode
- *
- * The code assumes that you do NOT have encoders on the wheels,
- * otherwise you would use: RobotAutoDriveByEncoder;
- *
- * The desired path in this example is:
- * - Drive forward for 3 seconds
- * - Spin right for 1.3 seconds
- * - Drive Backward for 1 Second
- *
- * The code is written in a simple form with no optimizations.
- * However, there are several ways that this type of sequence could be streamlined,
- *
- * 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
- */
-
-@Autonomous(name="Robot: Auto Drive By Time", group="Robot")
-@Disabled
-public class RobotAutoDriveByTime_Linear extends LinearOpMode {
-
- /* Declare OpMode members. */
- private DcMotor leftDrive = null;
- private DcMotor rightDrive = null;
-
- private ElapsedTime runtime = new ElapsedTime();
-
-
- static final double FORWARD_SPEED = 0.6;
- static final double TURN_SPEED = 0.5;
-
- @Override
- public void runOpMode() {
-
- // Initialize the drive system variables.
- leftDrive = hardwareMap.get(DcMotor.class, "left_drive");
- rightDrive = hardwareMap.get(DcMotor.class, "right_drive");
-
- // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
- // When run, this OpMode should start both motors driving forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Gear Reduction or 90 Deg drives may require direction flips
- leftDrive.setDirection(DcMotor.Direction.REVERSE);
- rightDrive.setDirection(DcMotor.Direction.FORWARD);
-
- // Send telemetry message to signify robot waiting;
- telemetry.addData("Status", "Ready to run"); //
- telemetry.update();
-
- // Wait for the game to start (driver presses START)
- waitForStart();
-
- // 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
- leftDrive.setPower(FORWARD_SPEED);
- rightDrive.setPower(FORWARD_SPEED);
- runtime.reset();
- while (opModeIsActive() && (runtime.seconds() < 3.0)) {
- telemetry.addData("Path", "Leg 1: %4.1f S Elapsed", runtime.seconds());
- telemetry.update();
- }
-
- // Step 2: Spin right for 1.3 seconds
- leftDrive.setPower(TURN_SPEED);
- rightDrive.setPower(-TURN_SPEED);
- runtime.reset();
- while (opModeIsActive() && (runtime.seconds() < 1.3)) {
- telemetry.addData("Path", "Leg 2: %4.1f S Elapsed", runtime.seconds());
- telemetry.update();
- }
-
- // Step 3: Drive Backward for 1 Second
- leftDrive.setPower(-FORWARD_SPEED);
- rightDrive.setPower(-FORWARD_SPEED);
- runtime.reset();
- while (opModeIsActive() && (runtime.seconds() < 1.0)) {
- telemetry.addData("Path", "Leg 3: %4.1f S Elapsed", runtime.seconds());
- telemetry.update();
- }
-
- // Step 4: Stop
- leftDrive.setPower(0);
- rightDrive.setPower(0);
-
- telemetry.addData("Path", "Complete");
- telemetry.update();
- sleep(1000);
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveToAprilTagOmni.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveToAprilTagOmni.java
deleted file mode 100644
index 9bac0069..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveToAprilTagOmni.java
+++ /dev/null
@@ -1,321 +0,0 @@
-/* Copyright (c) 2023 FIRST. 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 com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.util.Range;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.BuiltinCameraDirection;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.controls.ExposureControl;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.controls.GainControl;
-import org.firstinspires.ftc.vision.VisionPortal;
-import org.firstinspires.ftc.vision.apriltag.AprilTagDetection;
-import org.firstinspires.ftc.vision.apriltag.AprilTagProcessor;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/*
- * This OpMode illustrates using a camera to locate and drive towards a specific AprilTag.
- * The code assumes a Holonomic (Mecanum or X Drive) Robot.
- *
- * 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
- *
- * When an AprilTag in the TagLibrary is detected, the SDK provides location and orientation of the tag, relative to the camera.
- * This information is provided in the "ftcPose" member of the returned "detection", and is explained in the ftc-docs page linked below.
- * https://ftc-docs.firstinspires.org/apriltag-detection-values
- *
- * The drive goal is to rotate to keep the Tag centered in the camera, while strafing to be directly in front of the tag, and
- * driving towards the tag to achieve the desired distance.
- * To reduce any motion blur (which will interrupt the detection process) the Camera exposure is reduced to a very low value (5mS)
- * You can determine the best Exposure and Gain values by using the ConceptAprilTagOptimizeExposure OpMode in this Samples folder.
- *
- * 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.
- * 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.
- *
- * 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.
- *
- * Press and hold the *Left Bumper* to enable the automatic "Drive to target" mode.
- * Release the Left Bumper to return to manual driving mode.
- *
- * Under "Drive To Target" mode, the robot has three goals:
- * 1) Turn the robot to always keep the Tag centered on the camera frame. (Use the Target Bearing to turn the robot.)
- * 2) Strafe the robot towards the centerline of the Tag, so it approaches directly in front of the tag. (Use the Target Yaw to strafe the robot)
- * 3) Drive towards the Tag to get to the desired distance. (Use Tag Range to drive the robot forward/backward)
- *
- * Use DESIRED_DISTANCE to set how close you want the robot to get to the target.
- * Speed and Turn sensitivity can be adjusted using the SPEED_GAIN, STRAFE_GAIN and TURN_GAIN constants.
- *
- * Use Android Studio to Copy this Class, and Paste it into the TeamCode/src/main/java/org/firstinspires/ftc/teamcode folder.
- * Remove or comment out the @Disabled line to add this OpMode to the Driver Station OpMode list.
- *
- */
-
-@TeleOp(name="Omni Drive To AprilTag", group = "Concept")
-@Disabled
-public class RobotAutoDriveToAprilTagOmni extends LinearOpMode
-{
- // Adjust these numbers to suit your robot.
- final double DESIRED_DISTANCE = 12.0; // this is how close the camera should get to the target (inches)
-
- // 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.
- // 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". 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". 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". 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_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)
-
- private DcMotor leftFrontDrive = null; // Used to control the left front drive wheel
- private DcMotor rightFrontDrive = null; // Used to control the right front drive wheel
- private DcMotor leftBackDrive = null; // Used to control the left back drive wheel
- private DcMotor rightBackDrive = null; // Used to control the right back drive wheel
-
- private static final boolean USE_WEBCAM = true; // Set true to use a webcam, or false for a phone camera
- private static final int DESIRED_TAG_ID = -1; // Choose the tag you want to approach or set to -1 for ANY tag.
- private VisionPortal visionPortal; // Used to manage the video source.
- private AprilTagProcessor aprilTag; // Used for managing the AprilTag detection process.
- private AprilTagDetection desiredTag = null; // Used to hold the data for a detected AprilTag
-
- @Override public void runOpMode()
- {
- boolean targetFound = false; // Set to true when an AprilTag target is detected
- double drive = 0; // Desired forward power/speed (-1 to +1)
- double strafe = 0; // Desired strafe power/speed (-1 to +1)
- double turn = 0; // Desired turning power/speed (-1 to +1)
-
- // Initialize the Apriltag Detection process
- initAprilTag();
-
- // Initialize the hardware variables. Note that the strings used here as parameters
- // to 'get' must match the names assigned during the robot configuration.
- // step (using the FTC Robot Controller app on the phone).
- leftFrontDrive = hardwareMap.get(DcMotor.class, "leftfront_drive");
- rightFrontDrive = hardwareMap.get(DcMotor.class, "rightfront_drive");
- leftBackDrive = hardwareMap.get(DcMotor.class, "leftback_drive");
- rightBackDrive = hardwareMap.get(DcMotor.class, "rightback_drive");
-
- // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
- // When run, this OpMode should start both motors driving forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Gear Reduction or 90 Deg drives may require direction flips
- leftFrontDrive.setDirection(DcMotor.Direction.REVERSE);
- leftBackDrive.setDirection(DcMotor.Direction.REVERSE);
- rightFrontDrive.setDirection(DcMotor.Direction.FORWARD);
- rightBackDrive.setDirection(DcMotor.Direction.FORWARD);
-
- if (USE_WEBCAM)
- setManualExposure(6, 250); // Use low exposure time to reduce motion blur
-
- // Wait for driver to press start
- telemetry.addData("Camera preview on/off", "3 dots, Camera Stream");
- telemetry.addData(">", "Touch START to start OpMode");
- telemetry.update();
- waitForStart();
-
- while (opModeIsActive())
- {
- targetFound = false;
- desiredTag = null;
-
- // Step through the list of detected tags and look for a matching tag
- List currentDetections = aprilTag.getDetections();
- for (AprilTagDetection detection : currentDetections) {
- // Look to see if we have size info on this tag.
- if (detection.metadata != null) {
- // Check to see if we want to track towards this tag.
- if ((DESIRED_TAG_ID < 0) || (detection.id == DESIRED_TAG_ID)) {
- // Yes, we want to use this tag.
- targetFound = true;
- desiredTag = detection;
- break; // don't look any further.
- } else {
- // This tag is in the library, but we do not want to track it right now.
- telemetry.addData("Skipping", "Tag ID %d is not desired", detection.id);
- }
- } else {
- // This tag is NOT in the library, so we don't have enough information to track to it.
- telemetry.addData("Unknown", "Tag ID %d is not in TagLibrary", detection.id);
- }
- }
-
- // Tell the driver what we see, and what to do.
- if (targetFound) {
- telemetry.addData("\n>","HOLD Left-Bumper to Drive to Target\n");
- telemetry.addData("Found", "ID %d (%s)", desiredTag.id, desiredTag.metadata.name);
- telemetry.addData("Range", "%5.1f inches", desiredTag.ftcPose.range);
- telemetry.addData("Bearing","%3.0f degrees", desiredTag.ftcPose.bearing);
- telemetry.addData("Yaw","%3.0f degrees", desiredTag.ftcPose.yaw);
- } else {
- telemetry.addData("\n>","Drive using joysticks to find valid target\n");
- }
-
- // If Left Bumper is being pressed, AND we have found the desired target, Drive to target Automatically .
- if (gamepad1.left_bumper && targetFound) {
-
- // Determine heading, range and Yaw (tag image rotation) error so we can use them to control the robot automatically.
- double rangeError = (desiredTag.ftcPose.range - DESIRED_DISTANCE);
- double headingError = desiredTag.ftcPose.bearing;
- double yawError = desiredTag.ftcPose.yaw;
-
- // Use the speed and turn "gains" to calculate how we want the robot to move.
- drive = Range.clip(rangeError * SPEED_GAIN, -MAX_AUTO_SPEED, MAX_AUTO_SPEED);
- turn = Range.clip(headingError * TURN_GAIN, -MAX_AUTO_TURN, MAX_AUTO_TURN) ;
- strafe = Range.clip(-yawError * STRAFE_GAIN, -MAX_AUTO_STRAFE, MAX_AUTO_STRAFE);
-
- telemetry.addData("Auto","Drive %5.2f, Strafe %5.2f, Turn %5.2f ", drive, strafe, turn);
- } else {
-
- // drive using manual POV Joystick mode. Slow things down to make the robot more controlable.
- drive = -gamepad1.left_stick_y / 2.0; // Reduce drive rate to 50%.
- strafe = -gamepad1.left_stick_x / 2.0; // Reduce strafe rate to 50%.
- turn = -gamepad1.right_stick_x / 3.0; // Reduce turn rate to 33%.
- telemetry.addData("Manual","Drive %5.2f, Strafe %5.2f, Turn %5.2f ", drive, strafe, turn);
- }
- telemetry.update();
-
- // Apply desired axes motions to the drivetrain.
- moveRobot(drive, strafe, turn);
- sleep(10);
- }
- }
-
- /**
- * Move robot according to desired axes motions
- *
- * Positive X is forward
- *
- * Positive Y is strafe left
- *
- * Positive Yaw is counter-clockwise
- */
- public void moveRobot(double x, double y, double yaw) {
- // Calculate wheel powers.
- double leftFrontPower = x -y -yaw;
- double rightFrontPower = x +y +yaw;
- double leftBackPower = x +y -yaw;
- double rightBackPower = x -y +yaw;
-
- // Normalize wheel powers to be less than 1.0
- double max = Math.max(Math.abs(leftFrontPower), Math.abs(rightFrontPower));
- max = Math.max(max, Math.abs(leftBackPower));
- max = Math.max(max, Math.abs(rightBackPower));
-
- if (max > 1.0) {
- leftFrontPower /= max;
- rightFrontPower /= max;
- leftBackPower /= max;
- rightBackPower /= max;
- }
-
- // Send powers to the wheels.
- leftFrontDrive.setPower(leftFrontPower);
- rightFrontDrive.setPower(rightFrontPower);
- leftBackDrive.setPower(leftBackPower);
- rightBackDrive.setPower(rightBackPower);
- }
-
- /**
- * Initialize the AprilTag processor.
- */
- private void initAprilTag() {
- // Create the AprilTag processor by using a builder.
- aprilTag = new AprilTagProcessor.Builder().build();
-
- // Adjust Image Decimation to trade-off detection-range for detection-rate.
- // 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 = 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 5" Tag from 10 feet away at 30 Frames Per Second
- // Note: Decimation can be changed on-the-fly to adapt during a match.
- aprilTag.setDecimation(2);
-
- // Create the vision portal by using a builder.
- if (USE_WEBCAM) {
- visionPortal = new VisionPortal.Builder()
- .setCamera(hardwareMap.get(WebcamName.class, "Webcam 1"))
- .addProcessor(aprilTag)
- .build();
- } else {
- visionPortal = new VisionPortal.Builder()
- .setCamera(BuiltinCameraDirection.BACK)
- .addProcessor(aprilTag)
- .build();
- }
- }
-
- /*
- Manually set the camera gain and exposure.
- This can only be called AFTER calling initAprilTag(), and only works for Webcams;
- */
- private void setManualExposure(int exposureMS, int gain) {
- // Wait for the camera to be open, then use the controls
-
- if (visionPortal == null) {
- return;
- }
-
- // Make sure camera is streaming before we try to set the exposure controls
- if (visionPortal.getCameraState() != VisionPortal.CameraState.STREAMING) {
- telemetry.addData("Camera", "Waiting");
- telemetry.update();
- while (!isStopRequested() && (visionPortal.getCameraState() != VisionPortal.CameraState.STREAMING)) {
- sleep(20);
- }
- telemetry.addData("Camera", "Ready");
- telemetry.update();
- }
-
- // Set camera controls unless we are stopping.
- if (!isStopRequested())
- {
- ExposureControl exposureControl = visionPortal.getCameraControl(ExposureControl.class);
- if (exposureControl.getMode() != ExposureControl.Mode.Manual) {
- exposureControl.setMode(ExposureControl.Mode.Manual);
- sleep(50);
- }
- exposureControl.setExposure((long)exposureMS, TimeUnit.MILLISECONDS);
- sleep(20);
- GainControl gainControl = visionPortal.getCameraControl(GainControl.class);
- gainControl.setGain(gain);
- sleep(20);
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveToAprilTagTank.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveToAprilTagTank.java
deleted file mode 100644
index ba3eb4f9..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveToAprilTagTank.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/* Copyright (c) 2023 FIRST. 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 com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.util.Range;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.BuiltinCameraDirection;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.controls.ExposureControl;
-import org.firstinspires.ftc.robotcore.external.hardware.camera.controls.GainControl;
-import org.firstinspires.ftc.vision.VisionPortal;
-import org.firstinspires.ftc.vision.apriltag.AprilTagDetection;
-import org.firstinspires.ftc.vision.apriltag.AprilTagProcessor;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/*
- * This OpMode illustrates using a camera to locate and drive towards a specific AprilTag.
- * The code assumes a basic two-wheel (Tank) Robot Drivetrain
- *
- * 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
- *
- * When an AprilTag in the TagLibrary is detected, the SDK provides location and orientation of the tag, relative to the camera.
- * This information is provided in the "ftcPose" member of the returned "detection", and is explained in the ftc-docs page linked below.
- * https://ftc-docs.firstinspires.org/apriltag-detection-values
- *
- * The driving goal is to rotate to keep the tag centered in the camera, while driving towards the tag to achieve the desired distance.
- * To reduce any motion blur (which will interrupt the detection process) the Camera exposure is reduced to a very low value (5mS)
- * You can determine the best exposure and gain values by using the ConceptAprilTagOptimizeExposure OpMode in this Samples folder.
- *
- * 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;
- * 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.
- *
- * 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).
- *
- * Manually drive the robot until it displays Target data on the Driver Station.
- * Press and hold the *Left Bumper* to enable the automatic "Drive to target" mode.
- * Release the Left Bumper to return to manual driving mode.
- *
- * Under "Drive To Target" mode, the robot has two goals:
- * 1) Turn the robot to always keep the Tag centered on the camera frame. (Use the Target Bearing to turn the robot.)
- * 2) Drive towards the Tag to get to the desired distance. (Use Tag Range to drive the robot forward/backward)
- *
- * Use DESIRED_DISTANCE to set how close you want the robot to get to the target.
- * Speed and Turn sensitivity can be adjusted using the SPEED_GAIN and TURN_GAIN constants.
- *
- * Use Android Studio to Copy this Class, and Paste it into the TeamCode/src/main/java/org/firstinspires/ftc/teamcode folder.
- * Remove or comment out the @Disabled line to add this OpMode to the Driver Station OpMode list.
- *
- */
-
-@TeleOp(name="Tank Drive To AprilTag", group = "Concept")
-@Disabled
-public class RobotAutoDriveToAprilTagTank extends LinearOpMode
-{
- // Adjust these numbers to suit your robot.
- final double DESIRED_DISTANCE = 12.0; // this is how close the camera should get to the target (inches)
-
- // 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.
- // 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". 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". 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_TURN = 0.25; // Clip the turn speed to this max value (adjust for your robot)
-
- private DcMotor leftDrive = null; // Used to control the left drive wheel
- private DcMotor rightDrive = null; // Used to control the right drive wheel
-
- private static final boolean USE_WEBCAM = true; // Set true to use a webcam, or false for a phone camera
- private static final int DESIRED_TAG_ID = -1; // Choose the tag you want to approach or set to -1 for ANY tag.
- private VisionPortal visionPortal; // Used to manage the video source.
- private AprilTagProcessor aprilTag; // Used for managing the AprilTag detection process.
- private AprilTagDetection desiredTag = null; // Used to hold the data for a detected AprilTag
-
- @Override public void runOpMode()
- {
- boolean targetFound = false; // Set to true when an AprilTag target is detected
- double drive = 0; // Desired forward power/speed (-1 to +1) +ve is forward
- double turn = 0; // Desired turning power/speed (-1 to +1) +ve is CounterClockwise
-
- // Initialize the Apriltag Detection process
- initAprilTag();
-
- // Initialize the hardware variables. Note that the strings used here as parameters
- // to 'get' must match the names assigned during the robot configuration.
- // step (using the FTC Robot Controller app on the phone).
- leftDrive = hardwareMap.get(DcMotor.class, "left_drive");
- rightDrive = hardwareMap.get(DcMotor.class, "right_drive");
-
- // To drive forward, most robots need the motor on one side to be reversed because the axles point in opposite directions.
- // When run, this OpMode should start both motors driving forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Single Gear Reduction or 90 Deg drives may require direction flips
- leftDrive.setDirection(DcMotor.Direction.REVERSE);
- rightDrive.setDirection(DcMotor.Direction.FORWARD);
-
- if (USE_WEBCAM)
- setManualExposure(6, 250); // Use low exposure time to reduce motion blur
-
- // Wait for the driver to press Start
- telemetry.addData("Camera preview on/off", "3 dots, Camera Stream");
- telemetry.addData(">", "Touch START to start OpMode");
- telemetry.update();
- waitForStart();
-
- while (opModeIsActive())
- {
- targetFound = false;
- desiredTag = null;
-
- // Step through the list of detected tags and look for a matching tag
- List currentDetections = aprilTag.getDetections();
- for (AprilTagDetection detection : currentDetections) {
- // Look to see if we have size info on this tag.
- if (detection.metadata != null) {
- // Check to see if we want to track towards this tag.
- if ((DESIRED_TAG_ID < 0) || (detection.id == DESIRED_TAG_ID)) {
- // Yes, we want to use this tag.
- targetFound = true;
- desiredTag = detection;
- break; // don't look any further.
- } else {
- // This tag is in the library, but we do not want to track it right now.
- telemetry.addData("Skipping", "Tag ID %d is not desired", detection.id);
- }
- } else {
- // This tag is NOT in the library, so we don't have enough information to track to it.
- telemetry.addData("Unknown", "Tag ID %d is not in TagLibrary", detection.id);
- }
- }
-
- // Tell the driver what we see, and what to do.
- if (targetFound) {
- telemetry.addData("\n>","HOLD Left-Bumper to Drive to Target\n");
- telemetry.addData("Found", "ID %d (%s)", desiredTag.id, desiredTag.metadata.name);
- telemetry.addData("Range", "%5.1f inches", desiredTag.ftcPose.range);
- telemetry.addData("Bearing","%3.0f degrees", desiredTag.ftcPose.bearing);
- } else {
- telemetry.addData("\n>","Drive using joysticks to find valid target\n");
- }
-
- // If Left Bumper is being pressed, AND we have found the desired target, Drive to target Automatically .
- if (gamepad1.left_bumper && targetFound) {
-
- // Determine heading and range error so we can use them to control the robot automatically.
- double rangeError = (desiredTag.ftcPose.range - DESIRED_DISTANCE);
- double headingError = desiredTag.ftcPose.bearing;
-
- // Use the speed and turn "gains" to calculate how we want the robot to move. Clip it to the maximum
- drive = Range.clip(rangeError * SPEED_GAIN, -MAX_AUTO_SPEED, MAX_AUTO_SPEED);
- turn = Range.clip(headingError * TURN_GAIN, -MAX_AUTO_TURN, MAX_AUTO_TURN) ;
-
- telemetry.addData("Auto","Drive %5.2f, Turn %5.2f", drive, turn);
- } else {
-
- // drive using manual POV Joystick mode.
- drive = -gamepad1.left_stick_y / 2.0; // Reduce drive rate to 50%.
- turn = -gamepad1.right_stick_x / 4.0; // Reduce turn rate to 25%.
- telemetry.addData("Manual","Drive %5.2f, Turn %5.2f", drive, turn);
- }
- telemetry.update();
-
- // Apply desired axes motions to the drivetrain.
- moveRobot(drive, turn);
- sleep(10);
- }
- }
-
- /**
- * Move robot according to desired axes motions
- *
- * Positive X is forward
- *
- * Positive Yaw is counter-clockwise
- */
- public void moveRobot(double x, double yaw) {
- // Calculate left and right wheel powers.
- double leftPower = x - yaw;
- double rightPower = x + yaw;
-
- // Normalize wheel powers to be less than 1.0
- double max = Math.max(Math.abs(leftPower), Math.abs(rightPower));
- if (max >1.0) {
- leftPower /= max;
- rightPower /= max;
- }
-
- // Send powers to the wheels.
- leftDrive.setPower(leftPower);
- rightDrive.setPower(rightPower);
- }
-
- /**
- * Initialize the AprilTag processor.
- */
- private void initAprilTag() {
- // Create the AprilTag processor by using a builder.
- aprilTag = new AprilTagProcessor.Builder().build();
-
- // Adjust Image Decimation to trade-off detection-range for detection-rate.
- // 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 = 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 5" Tag from 10 feet away at 30 Frames Per Second
- // Note: Decimation can be changed on-the-fly to adapt during a match.
- aprilTag.setDecimation(2);
-
- // Create the vision portal by using a builder.
- if (USE_WEBCAM) {
- visionPortal = new VisionPortal.Builder()
- .setCamera(hardwareMap.get(WebcamName.class, "Webcam 1"))
- .addProcessor(aprilTag)
- .build();
- } else {
- visionPortal = new VisionPortal.Builder()
- .setCamera(BuiltinCameraDirection.BACK)
- .addProcessor(aprilTag)
- .build();
- }
- }
-
- /*
- Manually set the camera gain and exposure.
- This can only be called AFTER calling initAprilTag(), and only works for Webcams;
- */
- private void setManualExposure(int exposureMS, int gain) {
- // Wait for the camera to be open, then use the controls
-
- if (visionPortal == null) {
- return;
- }
-
- // Make sure camera is streaming before we try to set the exposure controls
- if (visionPortal.getCameraState() != VisionPortal.CameraState.STREAMING) {
- telemetry.addData("Camera", "Waiting");
- telemetry.update();
- while (!isStopRequested() && (visionPortal.getCameraState() != VisionPortal.CameraState.STREAMING)) {
- sleep(20);
- }
- telemetry.addData("Camera", "Ready");
- telemetry.update();
- }
-
- // Set camera controls unless we are stopping.
- if (!isStopRequested())
- {
- ExposureControl exposureControl = visionPortal.getCameraControl(ExposureControl.class);
- if (exposureControl.getMode() != ExposureControl.Mode.Manual) {
- exposureControl.setMode(ExposureControl.Mode.Manual);
- sleep(50);
- }
- exposureControl.setExposure((long)exposureMS, TimeUnit.MILLISECONDS);
- sleep(20);
- GainControl gainControl = visionPortal.getCameraControl(GainControl.class);
- gainControl.setGain(gain);
- sleep(20);
- telemetry.addData("Camera", "Ready");
- telemetry.update();
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveToLine_Linear.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveToLine_Linear.java
deleted file mode 100644
index 780f2604..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotAutoDriveToLine_Linear.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.Autonomous;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.hardware.NormalizedColorSensor;
-import com.qualcomm.robotcore.hardware.NormalizedRGBA;
-import com.qualcomm.robotcore.hardware.SwitchableLight;
-
-/*
- * This OpMode illustrates the concept of driving up to a line and then stopping.
- * The code is structured as a LinearOpMode
- *
- * The Sensor used here can be a REV Color Sensor V2 or V3. Make sure the white LED is turned on.
- * The sensor can be plugged into any I2C port, and must be named "sensor_color" in the active configuration.
- *
- * Depending on the height of your color sensor, you may want to set the sensor "gain".
- * The higher the gain, the greater the reflected light reading will be.
- * Use the SensorColor sample in this folder to determine the minimum gain value that provides an
- * "Alpha" reading of 1.0 when you are on top of the white line. In this sample, we use a gain of 15
- * which works well with a Rev V2 color sensor
- *
- * Setting the correct WHITE_THRESHOLD value is key to stopping correctly.
- * This should be set halfway between the bare-tile, and white-line "Alpha" values.
- * The reflected light value can be read on the screen once the OpMode has been INIT, but before it is STARTED.
- * Move the sensor on and off the white line and note the min and max readings.
- * Edit this code to make WHITE_THRESHOLD halfway between the min and max.
- *
- * 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
- */
-
-@Autonomous(name="Robot: Auto Drive To Line", group="Robot")
-@Disabled
-public class RobotAutoDriveToLine_Linear extends LinearOpMode {
-
- /* Declare OpMode members. */
- private DcMotor leftDrive = null;
- private DcMotor rightDrive = null;
-
- /** The variable to store a reference to our color sensor hardware object */
- NormalizedColorSensor colorSensor;
-
- static final double WHITE_THRESHOLD = 0.5; // spans between 0.0 - 1.0 from dark to light
- static final double APPROACH_SPEED = 0.25;
-
- @Override
- public void runOpMode() {
-
- // Initialize the drive system variables.
- leftDrive = hardwareMap.get(DcMotor.class, "left_drive");
- rightDrive = hardwareMap.get(DcMotor.class, "right_drive");
-
- // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
- // When run, this OpMode should start both motors driving forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Gear Reduction or 90 Deg drives may require direction flips
- leftDrive.setDirection(DcMotor.Direction.REVERSE);
- rightDrive.setDirection(DcMotor.Direction.FORWARD);
-
- // If there are encoders connected, switch to RUN_USING_ENCODER mode for greater accuracy
- // leftDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- // rightDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
-
- // Get a reference to our sensor object. It's recommended to use NormalizedColorSensor over
- // ColorSensor, because NormalizedColorSensor consistently gives values between 0 and 1, while
- // the values you get from ColorSensor are dependent on the specific sensor you're using.
- colorSensor = hardwareMap.get(NormalizedColorSensor.class, "sensor_color");
-
- // If necessary, turn ON the white LED (if there is no LED switch on the sensor)
- if (colorSensor instanceof SwitchableLight) {
- ((SwitchableLight)colorSensor).enableLight(true);
- }
-
- // Some sensors allow you to set your light sensor gain for optimal sensitivity...
- // See the SensorColor sample in this folder for how to determine the optimal gain.
- // 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);
-
- // Wait for driver to press START)
- // Abort this loop is started or stopped.
- while (opModeInInit()) {
-
- // Send telemetry message to signify robot waiting;
- telemetry.addData("Status", "Ready to drive to white line."); //
-
- // Display the light level while we are waiting to start
- getBrightness();
- }
-
- // Start the robot moving forward, and then begin looking for a white line.
- leftDrive.setPower(APPROACH_SPEED);
- rightDrive.setPower(APPROACH_SPEED);
-
- // run until the white line is seen OR the driver presses STOP;
- while (opModeIsActive() && (getBrightness() < WHITE_THRESHOLD)) {
- sleep(5);
- }
-
- // Stop all motors
- leftDrive.setPower(0);
- rightDrive.setPower(0);
- }
-
- // to obtain reflected light, read the normalized values from the color sensor. Return the Alpha channel.
- double getBrightness() {
- NormalizedRGBA colors = colorSensor.getNormalizedColors();
- telemetry.addData("Light Level (0 to 1)", "%4.2f", colors.alpha);
- telemetry.update();
-
- return colors.alpha;
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotHardware.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotHardware.java
deleted file mode 100644
index b1c8de62..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotHardware.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/* Copyright (c) 2022 FIRST. 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.LinearOpMode;
-import com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.hardware.Servo;
-import com.qualcomm.robotcore.util.Range;
-
-/*
- * This file works in conjunction with the External Hardware Class sample called: ConceptExternalHardwareClass.java
- * Please read the explanations in that Sample about how to use this class definition.
- *
- * This file defines a Java Class that performs all the setup and configuration for a sample robot's hardware (motors and sensors).
- * It assumes three motors (left_drive, right_drive and arm) and two servos (left_hand and right_hand)
- *
- * This one file/class can be used by ALL of your OpModes without having to cut & paste the code each time.
- *
- * Where possible, the actual hardware objects are "abstracted" (or hidden) so the OpMode code just makes calls into the class,
- * rather than accessing the internal hardware directly. This is why the objects are declared "private".
- *
- * Use Android Studio to Copy this Class, and Paste it into your team's code folder with *exactly the same name*.
- *
- * Or... In OnBot Java, add a new file named RobotHardware.java, select this sample, and select Not an OpMode.
- * Also add a new OpMode, select the sample ConceptExternalHardwareClass.java, and select TeleOp.
- *
- */
-
-public class RobotHardware {
-
- /* Declare OpMode members. */
- private LinearOpMode myOpMode = null; // gain access to methods in the calling OpMode.
-
- // Define Motor and Servo objects (Make them private so they can't be accessed externally)
- private DcMotor leftDrive = null;
- private DcMotor rightDrive = null;
- private DcMotor armMotor = null;
- private Servo leftHand = null;
- private Servo rightHand = null;
-
- // Define Drive constants. Make them public so they CAN be used by the calling OpMode
- public static final double MID_SERVO = 0.5 ;
- public static final double HAND_SPEED = 0.02 ; // sets rate to move servo
- public static final double ARM_UP_POWER = 0.45 ;
- public static final double ARM_DOWN_POWER = -0.45 ;
-
- // Define a constructor that allows the OpMode to pass a reference to itself.
- public RobotHardware (LinearOpMode opmode) {
- myOpMode = opmode;
- }
-
- /**
- * Initialize all the robot's hardware.
- * This method must be called ONCE when the OpMode is initialized.
- *
- * All of the hardware devices are accessed via the hardware map, and initialized.
- */
- public void init() {
- // Define and Initialize Motors (note: need to use reference to actual OpMode).
- leftDrive = myOpMode.hardwareMap.get(DcMotor.class, "left_drive");
- rightDrive = myOpMode.hardwareMap.get(DcMotor.class, "right_drive");
- armMotor = myOpMode.hardwareMap.get(DcMotor.class, "arm");
-
- // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
- // Pushing the left stick forward MUST make robot go forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Gear Reduction or 90 Deg drives may require direction flips
- leftDrive.setDirection(DcMotor.Direction.REVERSE);
- rightDrive.setDirection(DcMotor.Direction.FORWARD);
-
- // If there are encoders connected, switch to RUN_USING_ENCODER mode for greater accuracy
- // leftDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- // rightDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
-
- // Define and initialize ALL installed servos.
- leftHand = myOpMode.hardwareMap.get(Servo.class, "left_hand");
- rightHand = myOpMode.hardwareMap.get(Servo.class, "right_hand");
- leftHand.setPosition(MID_SERVO);
- rightHand.setPosition(MID_SERVO);
-
- myOpMode.telemetry.addData(">", "Hardware Initialized");
- myOpMode.telemetry.update();
- }
-
- /**
- * Calculates the left/right motor powers required to achieve the requested
- * robot motions: Drive (Axial motion) and Turn (Yaw motion).
- * Then sends these power levels to the motors.
- *
- * @param Drive Fwd/Rev driving power (-1.0 to 1.0) +ve is forward
- * @param Turn Right/Left turning power (-1.0 to 1.0) +ve is CW
- */
- public void driveRobot(double Drive, double Turn) {
- // Combine drive and turn for blended motion.
- double left = Drive + Turn;
- double right = Drive - Turn;
-
- // Scale the values so neither exceed +/- 1.0
- double max = Math.max(Math.abs(left), Math.abs(right));
- if (max > 1.0)
- {
- left /= max;
- right /= max;
- }
-
- // Use existing function to drive both wheels.
- setDrivePower(left, right);
- }
-
- /**
- * Pass the requested wheel motor powers to the appropriate hardware drive motors.
- *
- * @param leftWheel Fwd/Rev driving power (-1.0 to 1.0) +ve is forward
- * @param rightWheel Fwd/Rev driving power (-1.0 to 1.0) +ve is forward
- */
- public void setDrivePower(double leftWheel, double rightWheel) {
- // Output the values to the motor drives.
- leftDrive.setPower(leftWheel);
- rightDrive.setPower(rightWheel);
- }
-
- /**
- * Pass the requested arm power to the appropriate hardware drive motor
- *
- * @param power driving power (-1.0 to 1.0)
- */
- public void setArmPower(double power) {
- armMotor.setPower(power);
- }
-
- /**
- * Send the two hand-servos to opposing (mirrored) positions, based on the passed offset.
- *
- * @param offset
- */
- public void setHandPositions(double offset) {
- offset = Range.clip(offset, -0.5, 0.5);
- leftHand.setPosition(MID_SERVO + offset);
- rightHand.setPosition(MID_SERVO - offset);
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotTeleopPOV_Linear.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotTeleopPOV_Linear.java
deleted file mode 100644
index af3840d3..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotTeleopPOV_Linear.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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 com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.hardware.Servo;
-import com.qualcomm.robotcore.util.Range;
-
-/*
- * This OpMode executes a POV Game style Teleop for a direct drive robot
- * The code is structured as a LinearOpMode
- *
- * In this mode the left stick moves the robot FWD and back, the Right stick turns left and right.
- * It raises and lowers the arm using the Gamepad Y and A buttons respectively.
- * It also opens and closes the claws slowly using the left and right Bumper buttons.
- *
- * 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="Robot: Teleop POV", group="Robot")
-@Disabled
-public class RobotTeleopPOV_Linear extends LinearOpMode {
-
- /* Declare OpMode members. */
- public DcMotor leftDrive = null;
- public DcMotor rightDrive = null;
- public DcMotor leftArm = null;
- public Servo leftClaw = null;
- public Servo rightClaw = null;
-
- double clawOffset = 0;
-
- public static final double MID_SERVO = 0.5 ;
- public static final double CLAW_SPEED = 0.02 ; // sets rate to move servo
- public static final double ARM_UP_POWER = 0.45 ;
- public static final double ARM_DOWN_POWER = -0.45 ;
-
- @Override
- public void runOpMode() {
- double left;
- double right;
- double drive;
- double turn;
- double max;
-
- // Define and Initialize Motors
- leftDrive = hardwareMap.get(DcMotor.class, "left_drive");
- rightDrive = hardwareMap.get(DcMotor.class, "right_drive");
- leftArm = hardwareMap.get(DcMotor.class, "left_arm");
-
- // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
- // Pushing the left stick forward MUST make robot go forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Gear Reduction or 90 Deg drives may require direction flips
- leftDrive.setDirection(DcMotor.Direction.REVERSE);
- rightDrive.setDirection(DcMotor.Direction.FORWARD);
-
- // If there are encoders connected, switch to RUN_USING_ENCODER mode for greater accuracy
- // leftDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- // rightDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
-
- // Define and initialize ALL installed servos.
- leftClaw = hardwareMap.get(Servo.class, "left_hand");
- rightClaw = hardwareMap.get(Servo.class, "right_hand");
- leftClaw.setPosition(MID_SERVO);
- rightClaw.setPosition(MID_SERVO);
-
- // Send telemetry message to signify robot waiting;
- telemetry.addData(">", "Robot Ready. Press START."); //
- telemetry.update();
-
- // Wait for the game to start (driver presses START)
- waitForStart();
-
- // run until the end of the match (driver presses STOP)
- while (opModeIsActive()) {
-
- // Run wheels in POV mode (note: The joystick goes negative when pushed forward, so negate it)
- // In this mode the Left stick moves the robot fwd and back, the Right stick turns left and right.
- // This way it's also easy to just drive straight, or just turn.
- drive = -gamepad1.left_stick_y;
- turn = gamepad1.right_stick_x;
-
- // Combine drive and turn for blended motion.
- left = drive + turn;
- right = drive - turn;
-
- // Normalize the values so neither exceed +/- 1.0
- max = Math.max(Math.abs(left), Math.abs(right));
- if (max > 1.0)
- {
- left /= max;
- right /= max;
- }
-
- // Output the safe vales to the motor drives.
- leftDrive.setPower(left);
- rightDrive.setPower(right);
-
- // Use gamepad left & right Bumpers to open and close the claw
- if (gamepad1.right_bumper)
- clawOffset += CLAW_SPEED;
- else if (gamepad1.left_bumper)
- clawOffset -= CLAW_SPEED;
-
- // Move both servos to new position. Assume servos are mirror image of each other.
- clawOffset = Range.clip(clawOffset, -0.5, 0.5);
- leftClaw.setPosition(MID_SERVO + clawOffset);
- rightClaw.setPosition(MID_SERVO - clawOffset);
-
- // Use gamepad buttons to move arm up (Y) and down (A)
- if (gamepad1.y)
- leftArm.setPower(ARM_UP_POWER);
- else if (gamepad1.a)
- leftArm.setPower(ARM_DOWN_POWER);
- else
- leftArm.setPower(0.0);
-
- // Send telemetry message to signify robot running;
- telemetry.addData("claw", "Offset = %.2f", clawOffset);
- telemetry.addData("left", "%.2f", left);
- telemetry.addData("right", "%.2f", right);
- telemetry.update();
-
- // Pace this loop so jaw action is reasonable speed.
- sleep(50);
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotTeleopTank_Iterative.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotTeleopTank_Iterative.java
deleted file mode 100644
index a622f27b..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotTeleopTank_Iterative.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.OpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.DcMotor;
-import com.qualcomm.robotcore.hardware.Servo;
-import com.qualcomm.robotcore.util.Range;
-
-/*
- * This OpMode executes a Tank Drive control TeleOp a direct drive robot
- * The code is structured as an Iterative OpMode
- *
- * In this mode, the left and right joysticks control the left and right motors respectively.
- * Pushing a joystick forward will make the attached motor drive forward.
- * It raises and lowers the claw using the Gamepad Y and A buttons respectively.
- * It also opens and closes the claws slowly using the left and right Bumper buttons.
- *
- * 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="Robot: Teleop Tank", group="Robot")
-@Disabled
-public class RobotTeleopTank_Iterative extends OpMode{
-
- /* Declare OpMode members. */
- public DcMotor leftDrive = null;
- public DcMotor rightDrive = null;
- public DcMotor leftArm = null;
- public Servo leftClaw = null;
- public Servo rightClaw = null;
-
- double clawOffset = 0;
-
- public static final double MID_SERVO = 0.5 ;
- public static final double CLAW_SPEED = 0.02 ; // sets rate to move servo
- public static final double ARM_UP_POWER = 0.50 ; // Run arm motor up at 50% power
- public static final double ARM_DOWN_POWER = -0.25 ; // Run arm motor down at -25% power
-
- /*
- * Code to run ONCE when the driver hits INIT
- */
- @Override
- public void init() {
- // Define and Initialize Motors
- leftDrive = hardwareMap.get(DcMotor.class, "left_drive");
- rightDrive = hardwareMap.get(DcMotor.class, "right_drive");
- leftArm = hardwareMap.get(DcMotor.class, "left_arm");
-
- // To drive forward, most robots need the motor on one side to be reversed, because the axles point in opposite directions.
- // Pushing the left and right sticks forward MUST make robot go forward. So adjust these two lines based on your first test drive.
- // Note: The settings here assume direct drive on left and right wheels. Gear Reduction or 90 Deg drives may require direction flips
- leftDrive.setDirection(DcMotor.Direction.REVERSE);
- rightDrive.setDirection(DcMotor.Direction.FORWARD);
-
- // If there are encoders connected, switch to RUN_USING_ENCODER mode for greater accuracy
- // leftDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
- // rightDrive.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
-
- // Define and initialize ALL installed servos.
- leftClaw = hardwareMap.get(Servo.class, "left_hand");
- rightClaw = hardwareMap.get(Servo.class, "right_hand");
- leftClaw.setPosition(MID_SERVO);
- rightClaw.setPosition(MID_SERVO);
-
- // Send telemetry message to signify robot waiting;
- telemetry.addData(">", "Robot Ready. Press START."); //
- }
-
- /*
- * Code to run REPEATEDLY after the driver hits INIT, but before they hit START
- */
- @Override
- public void init_loop() {
- }
-
- /*
- * Code to run ONCE when the driver hits START
- */
- @Override
- public void start() {
- }
-
- /*
- * Code to run REPEATEDLY after the driver hits START but before they hit STOP
- */
- @Override
- public void loop() {
- double left;
- double right;
-
- // Run wheels in tank mode (note: The joystick goes negative when pushed forward, so negate it)
- left = -gamepad1.left_stick_y;
- right = -gamepad1.right_stick_y;
-
- leftDrive.setPower(left);
- rightDrive.setPower(right);
-
- // Use gamepad left & right Bumpers to open and close the claw
- if (gamepad1.right_bumper)
- clawOffset += CLAW_SPEED;
- else if (gamepad1.left_bumper)
- clawOffset -= CLAW_SPEED;
-
- // Move both servos to new position. Assume servos are mirror image of each other.
- clawOffset = Range.clip(clawOffset, -0.5, 0.5);
- leftClaw.setPosition(MID_SERVO + clawOffset);
- rightClaw.setPosition(MID_SERVO - clawOffset);
-
- // Use gamepad buttons to move the arm up (Y) and down (A)
- if (gamepad1.y)
- leftArm.setPower(ARM_UP_POWER);
- else if (gamepad1.a)
- leftArm.setPower(ARM_DOWN_POWER);
- else
- leftArm.setPower(0.0);
-
- // Send telemetry message to signify robot running;
- telemetry.addData("claw", "Offset = %.2f", clawOffset);
- telemetry.addData("left", "%.2f", left);
- telemetry.addData("right", "%.2f", right);
- }
-
- /*
- * Code to run ONCE after the driver hits STOP
- */
- @Override
- public void stop() {
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SampleRevBlinkinLedDriver.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SampleRevBlinkinLedDriver.java
deleted file mode 100644
index bcf5b80e..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SampleRevBlinkinLedDriver.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 2018 Craig MacFarlane
- *
- * 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 Craig MacFarlane 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.rev.RevBlinkinLedDriver;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.OpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import org.firstinspires.ftc.robotcore.external.Telemetry;
-import org.firstinspires.ftc.robotcore.internal.system.Deadline;
-
-import java.util.concurrent.TimeUnit;
-
-/*
- * This OpMode demonstrates use of the REV Robotics Blinkin LED Driver.
- * AUTO mode cycles through all of the patterns.
- * MANUAL mode allows the user to manually change patterns using the
- * left and right bumpers of a gamepad.
- *
- * Configure the driver on a servo port, and name it "blinkin".
- *
- * Displays the first pattern upon init.
- */
-@TeleOp(name="BlinkinExample")
-@Disabled
-public class SampleRevBlinkinLedDriver extends OpMode {
-
- /*
- * Change the pattern every 10 seconds in AUTO mode.
- */
- private final static int LED_PERIOD = 10;
-
- /*
- * Rate limit gamepad button presses to every 500ms.
- */
- private final static int GAMEPAD_LOCKOUT = 500;
-
- RevBlinkinLedDriver blinkinLedDriver;
- RevBlinkinLedDriver.BlinkinPattern pattern;
-
- Telemetry.Item patternName;
- Telemetry.Item display;
- DisplayKind displayKind;
- Deadline ledCycleDeadline;
- Deadline gamepadRateLimit;
-
- protected enum DisplayKind {
- MANUAL,
- AUTO
- }
-
- @Override
- public void init()
- {
- displayKind = DisplayKind.AUTO;
-
- blinkinLedDriver = hardwareMap.get(RevBlinkinLedDriver.class, "blinkin");
- pattern = RevBlinkinLedDriver.BlinkinPattern.RAINBOW_RAINBOW_PALETTE;
- blinkinLedDriver.setPattern(pattern);
-
- display = telemetry.addData("Display Kind: ", displayKind.toString());
- patternName = telemetry.addData("Pattern: ", pattern.toString());
-
- ledCycleDeadline = new Deadline(LED_PERIOD, TimeUnit.SECONDS);
- gamepadRateLimit = new Deadline(GAMEPAD_LOCKOUT, TimeUnit.MILLISECONDS);
- }
-
- @Override
- public void loop()
- {
- handleGamepad();
-
- if (displayKind == DisplayKind.AUTO) {
- doAutoDisplay();
- } else {
- /*
- * MANUAL mode: Nothing to do, setting the pattern as a result of a gamepad event.
- */
- }
- }
-
- /*
- * handleGamepad
- *
- * Responds to a gamepad button press. Demonstrates rate limiting for
- * button presses. If loop() is called every 10ms and and you don't rate
- * limit, then any given button press may register as multiple button presses,
- * which in this application is problematic.
- *
- * A: Manual mode, Right bumper displays the next pattern, left bumper displays the previous pattern.
- * B: Auto mode, pattern cycles, changing every LED_PERIOD seconds.
- */
- protected void handleGamepad()
- {
- if (!gamepadRateLimit.hasExpired()) {
- return;
- }
-
- if (gamepad1.a) {
- setDisplayKind(DisplayKind.MANUAL);
- gamepadRateLimit.reset();
- } else if (gamepad1.b) {
- setDisplayKind(DisplayKind.AUTO);
- gamepadRateLimit.reset();
- } else if ((displayKind == DisplayKind.MANUAL) && (gamepad1.left_bumper)) {
- pattern = pattern.previous();
- displayPattern();
- gamepadRateLimit.reset();
- } else if ((displayKind == DisplayKind.MANUAL) && (gamepad1.right_bumper)) {
- pattern = pattern.next();
- displayPattern();
- gamepadRateLimit.reset();
- }
- }
-
- protected void setDisplayKind(DisplayKind displayKind)
- {
- this.displayKind = displayKind;
- display.setValue(displayKind.toString());
- }
-
- protected void doAutoDisplay()
- {
- if (ledCycleDeadline.hasExpired()) {
- pattern = pattern.next();
- displayPattern();
- ledCycleDeadline.reset();
- }
- }
-
- protected void displayPattern()
- {
- blinkinLedDriver.setPattern(pattern);
- patternName.setValue(pattern.toString());
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMU.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMU.java
deleted file mode 100644
index 405da1e9..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMU.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.bosch.BNO055IMU;
-import com.qualcomm.hardware.bosch.JustLoggingAccelerationIntegrator;
-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.Func;
-import org.firstinspires.ftc.robotcore.external.navigation.Acceleration;
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-import org.firstinspires.ftc.robotcore.external.navigation.AxesOrder;
-import org.firstinspires.ftc.robotcore.external.navigation.AxesReference;
-import org.firstinspires.ftc.robotcore.external.navigation.Orientation;
-import org.firstinspires.ftc.robotcore.external.navigation.Position;
-import org.firstinspires.ftc.robotcore.external.navigation.Velocity;
-
-import java.util.Locale;
-
-/*
- * This OpMode gives a short demo on how to use the BNO055 Inertial Motion Unit (IMU) from AdaFruit.
- *
- * Note: this is a Legacy example that will not work with newer Control/Expansion Hubs that use a different IMU
- * Please use the new SensorIMUOrthogonal or SensorIMUNonOrthogonal samples for a more universal IMU interface.
- *
- * 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
- *
- * @see Adafruit IMU
- */
-@TeleOp(name = "Sensor: BNO055 IMU", group = "Sensor")
-@Disabled // Comment this out to add to the OpMode list
-public class SensorBNO055IMU extends LinearOpMode
- {
- //----------------------------------------------------------------------------------------------
- // State
- //----------------------------------------------------------------------------------------------
-
- // The IMU sensor object
- BNO055IMU imu;
-
- // State used for updating telemetry
- Orientation angles;
- Acceleration gravity;
-
- //----------------------------------------------------------------------------------------------
- // Main logic
- //----------------------------------------------------------------------------------------------
-
- @Override public void runOpMode() {
-
- // Set up the parameters with which we will use our IMU. Note that integration
- // algorithm here just reports accelerations to the logcat log; it doesn't actually
- // provide positional information.
- BNO055IMU.Parameters parameters = new BNO055IMU.Parameters();
- parameters.angleUnit = BNO055IMU.AngleUnit.DEGREES;
- parameters.accelUnit = BNO055IMU.AccelUnit.METERS_PERSEC_PERSEC;
- parameters.calibrationDataFile = "BNO055IMUCalibration.json"; // see the calibration sample OpMode
- parameters.loggingEnabled = true;
- parameters.loggingTag = "IMU";
- parameters.accelerationIntegrationAlgorithm = new JustLoggingAccelerationIntegrator();
-
- // Retrieve and initialize the IMU. We expect the IMU to be attached to an I2C port
- // on a Core Device Interface Module, configured to be a sensor of type "AdaFruit IMU",
- // and named "imu".
- imu = hardwareMap.get(BNO055IMU.class, "imu");
- imu.initialize(parameters);
-
- // Set up our telemetry dashboard
- composeTelemetry();
-
- // Wait until we're told to go
- waitForStart();
-
- // Start the logging of measured acceleration
- imu.startAccelerationIntegration(new Position(), new Velocity(), 1000);
-
- // Loop and update the dashboard
- while (opModeIsActive()) {
- telemetry.update();
- }
- }
-
- //----------------------------------------------------------------------------------------------
- // Telemetry Configuration
- //----------------------------------------------------------------------------------------------
-
- void composeTelemetry() {
-
- // At the beginning of each telemetry update, grab a bunch of data
- // from the IMU that we will then display in separate lines.
- telemetry.addAction(new Runnable() { @Override public void run()
- {
- // Acquiring the angles is relatively expensive; we don't want
- // to do that in each of the three items that need that info, as that's
- // three times the necessary expense.
- angles = imu.getAngularOrientation(AxesReference.INTRINSIC, AxesOrder.ZYX, AngleUnit.DEGREES);
- gravity = imu.getGravity();
- }
- });
-
- telemetry.addLine()
- .addData("status", new Func() {
- @Override public String value() {
- return imu.getSystemStatus().toShortString();
- }
- })
- .addData("calib", new Func() {
- @Override public String value() {
- return imu.getCalibrationStatus().toString();
- }
- });
-
- telemetry.addLine()
- .addData("heading", new Func() {
- @Override public String value() {
- return formatAngle(angles.angleUnit, angles.firstAngle);
- }
- })
- .addData("roll", new Func() {
- @Override public String value() {
- return formatAngle(angles.angleUnit, angles.secondAngle);
- }
- })
- .addData("pitch", new Func() {
- @Override public String value() {
- return formatAngle(angles.angleUnit, angles.thirdAngle);
- }
- });
-
- telemetry.addLine()
- .addData("grvty", new Func() {
- @Override public String value() {
- return gravity.toString();
- }
- })
- .addData("mag", new Func() {
- @Override public String value() {
- return String.format(Locale.getDefault(), "%.3f",
- Math.sqrt(gravity.xAccel*gravity.xAccel
- + gravity.yAccel*gravity.yAccel
- + gravity.zAccel*gravity.zAccel));
- }
- });
- }
-
- //----------------------------------------------------------------------------------------------
- // Formatting
- //----------------------------------------------------------------------------------------------
-
- String formatAngle(AngleUnit angleUnit, double angle) {
- return formatDegrees(AngleUnit.DEGREES.fromUnit(angleUnit, angle));
- }
-
- String formatDegrees(double degrees){
- return String.format(Locale.getDefault(), "%.1f", AngleUnit.DEGREES.normalize(degrees));
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMUCalibration.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMUCalibration.java
deleted file mode 100644
index 93f1789d..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMUCalibration.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.bosch.BNO055IMU;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.util.ReadWriteFile;
-import org.firstinspires.ftc.robotcore.external.Func;
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-import org.firstinspires.ftc.robotcore.external.navigation.AxesOrder;
-import org.firstinspires.ftc.robotcore.external.navigation.AxesReference;
-import org.firstinspires.ftc.robotcore.external.navigation.Orientation;
-import org.firstinspires.ftc.robotcore.internal.system.AppUtil;
-
-import java.io.File;
-import java.util.Locale;
-
-/*
- * This OpMode calibrates a BNO055 IMU per
- * "Section 3.11 Calibration" of the BNO055 specification.
- *
- * Note: this is a Legacy example that will not work with newer Control/Expansion Hubs that use a different IMU
- * Please use the new SensorIMUOrthogonal or SensorIMUNonOrthogonal samples for a more universal IMU interface.
- *
- * Manual calibration of the IMU is definitely NOT necessary: except for the magnetometer (which is not used by the
- * default "IMU" SensorMode), the BNO055 is internally self-calibrating and thus can be very successfully used without
- * manual intervention. That said, performing a one-time calibration, saving the results persistently, then loading them
- * again at each run can help reduce the time that automatic calibration requires.
- *
- * This summary of the calibration process from Intel is informative:
- * http://iotdk.intel.com/docs/master/upm/classupm_1_1_b_n_o055.html
- *
- * "This device requires calibration in order to operate accurately. [...] Calibration data is
- * lost on a power cycle. See one of the examples for a description of how to calibrate the device,
- * but in essence:
- *
- * There is a calibration status register available [...] that returns the calibration status
- * of the accelerometer (ACC), magnetometer (MAG), gyroscope (GYR), and overall system (SYS).
- * Each of these values range from 0 (uncalibrated) to 3 (fully calibrated). Calibration [ideally]
- * involves certain motions to get all 4 values at 3. The motions are as follows (though see the
- * datasheet for more information):
- *
- * 1. GYR: Simply let the sensor sit flat for a few seconds.
- * 2. ACC: Move the sensor in various positions. Start flat, then rotate slowly by 45
- * degrees, hold for a few seconds, then continue rotating another 45 degrees and
- * hold, etc. 6 or more movements of this type may be required. You can move through
- * any axis you desire, but make sure that the device is lying at least once
- * perpendicular to the x, y, and z axis.
- * 3. MAG: Move slowly in a figure 8 pattern in the air, until the calibration values reaches 3.
- * 4. SYS: This will usually reach 3 when the other items have also reached 3. If not, continue
- * slowly moving the device though various axes until it does."
- *
- * To calibrate the IMU, run this sample OpMode with a gamepad attached to the driver station.
- * Once the IMU has reached sufficient calibration as reported on telemetry, press the 'A'
- * button on the gamepad to write the calibration to a file. That file can then be indicated
- * later when running an OpMode which uses the IMU.
- *
- * Note: if your intended uses of the IMU do not include use of all its sensors (for example,
- * you might not use the magnetometer), then it makes little sense for you to wait for full
- * calibration of the sensors you are not using before saving the calibration data. Indeed,
- * it appears that in a SensorMode that doesn't use the magnetometer (for example), the
- * magnetometer cannot actually be calibrated.
- *
- * References:
- * The AdafruitBNO055IMU Javadoc
- * The BNO055IMU.Parameters.calibrationDataFile Javadoc
- * The BNO055 product page: https://www.bosch-sensortec.com/bst/products/all_products/bno055
- * The BNO055 datasheet: https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bno055-ds000.pdf
- */
-@TeleOp(name = "Sensor: BNO055 IMU Calibration", group = "Sensor")
-@Disabled // Uncomment this to add to the OpMode list
-public class SensorBNO055IMUCalibration extends LinearOpMode
- {
- //----------------------------------------------------------------------------------------------
- // State
- //----------------------------------------------------------------------------------------------
-
- // Our sensors, motors, and other devices go here, along with other long term state
- BNO055IMU imu;
-
- // State used for updating telemetry
- Orientation angles;
-
- //----------------------------------------------------------------------------------------------
- // Main logic
- //----------------------------------------------------------------------------------------------
-
- @Override public void runOpMode() {
-
- telemetry.log().setCapacity(12);
- telemetry.log().add("");
- telemetry.log().add("Please refer to the calibration instructions");
- telemetry.log().add("contained in the Adafruit IMU calibration");
- telemetry.log().add("sample OpMode.");
- telemetry.log().add("");
- telemetry.log().add("When sufficient calibration has been reached,");
- telemetry.log().add("press the 'A' button to write the current");
- telemetry.log().add("calibration data to a file.");
- telemetry.log().add("");
-
- // We are expecting the IMU to be attached to an I2C port on a Core Device Interface Module and named "imu".
- BNO055IMU.Parameters parameters = new BNO055IMU.Parameters();
- parameters.loggingEnabled = true;
- parameters.loggingTag = "IMU";
- imu = hardwareMap.get(BNO055IMU.class, "imu");
- imu.initialize(parameters);
-
- composeTelemetry();
- telemetry.log().add("Waiting for start...");
-
- // Wait until we're told to go
- while (!isStarted()) {
- telemetry.update();
- idle();
- }
-
- telemetry.log().add("...started...");
-
- while (opModeIsActive()) {
-
- if (gamepad1.a) {
-
- // Get the calibration data
- BNO055IMU.CalibrationData calibrationData = imu.readCalibrationData();
-
- // Save the calibration data to a file. You can choose whatever file
- // name you wish here, but you'll want to indicate the same file name
- // when you initialize the IMU in an OpMode in which it is used. If you
- // have more than one IMU on your robot, you'll of course want to use
- // different configuration file names for each.
- String filename = "AdafruitIMUCalibration.json";
- File file = AppUtil.getInstance().getSettingsFile(filename);
- ReadWriteFile.writeFile(file, calibrationData.serialize());
- telemetry.log().add("saved to '%s'", filename);
-
- // Wait for the button to be released
- while (gamepad1.a) {
- telemetry.update();
- idle();
- }
- }
-
- telemetry.update();
- }
- }
-
- void composeTelemetry() {
-
- // At the beginning of each telemetry update, grab a bunch of data
- // from the IMU that we will then display in separate lines.
- telemetry.addAction(new Runnable() { @Override public void run()
- {
- // Acquiring the angles is relatively expensive; we don't want
- // to do that in each of the three items that need that info, as that's
- // three times the necessary expense.
- angles = imu.getAngularOrientation(AxesReference.INTRINSIC, AxesOrder.ZYX, AngleUnit.DEGREES);
- }
- });
-
- telemetry.addLine()
- .addData("status", new Func() {
- @Override public String value() {
- return imu.getSystemStatus().toShortString();
- }
- })
- .addData("calib", new Func() {
- @Override public String value() {
- return imu.getCalibrationStatus().toString();
- }
- });
-
- telemetry.addLine()
- .addData("heading", new Func() {
- @Override public String value() {
- return formatAngle(angles.angleUnit, angles.firstAngle);
- }
- })
- .addData("roll", new Func() {
- @Override public String value() {
- return formatAngle(angles.angleUnit, angles.secondAngle);
- }
- })
- .addData("pitch", new Func() {
- @Override public String value() {
- return formatAngle(angles.angleUnit, angles.thirdAngle);
- }
- });
- }
-
- //----------------------------------------------------------------------------------------------
- // Formatting
- //----------------------------------------------------------------------------------------------
-
- String formatAngle(AngleUnit angleUnit, double angle) {
- return formatDegrees(AngleUnit.DEGREES.fromUnit(angleUnit, angle));
- }
-
- String formatDegrees(double degrees){
- return String.format(Locale.getDefault(), "%.1f", AngleUnit.DEGREES.normalize(degrees));
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorColor.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorColor.java
deleted file mode 100644
index 7546c9de..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorColor.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/* Copyright (c) 2017-2020 FIRST. 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 android.app.Activity;
-import android.graphics.Color;
-import android.view.View;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.DistanceSensor;
-import com.qualcomm.robotcore.hardware.NormalizedColorSensor;
-import com.qualcomm.robotcore.hardware.NormalizedRGBA;
-import com.qualcomm.robotcore.hardware.SwitchableLight;
-import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit;
-
-/*
- * This OpMode shows how to use a color sensor in a generic
- * way, regardless of which particular make or model of color sensor is used. The OpMode
- * assumes that the color sensor is configured with a name of "sensor_color".
- *
- * There will be some variation in the values measured depending on the specific sensor you are using.
- *
- * You can increase the gain (a multiplier to make the sensor report higher values) by holding down
- * the A button on the gamepad, and decrease the gain by holding down the B button on the gamepad.
- *
- * If the color sensor has a light which is controllable from software, you can use the X button on
- * the gamepad to toggle the light on and off. The REV sensors don't support this, but instead have
- * a physical switch on them to turn the light on and off, beginning with REV Color Sensor V2.
- *
- * If the color sensor also supports short-range distance measurements (usually via an infrared
- * proximity sensor), the reported distance will be written to telemetry. As of September 2020,
- * the only color sensors that support this are the ones from REV Robotics. These infrared proximity
- * sensor measurements are only useful at very small distances, and are sensitive to ambient light
- * and surface reflectivity. You should use a different sensor if you need precise distance measurements.
- *
- * 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 = "Sensor: Color", group = "Sensor")
-@Disabled
-public class SensorColor extends LinearOpMode {
-
- /** The colorSensor field will contain a reference to our color sensor hardware object */
- NormalizedColorSensor colorSensor;
-
- /** The relativeLayout field is used to aid in providing interesting visual feedback
- * in this sample application; you probably *don't* need this when you use a color sensor on your
- * robot. Note that you won't see anything change on the Driver Station, only on the Robot Controller. */
- View relativeLayout;
-
- /*
- * The runOpMode() method is the root of this OpMode, as it is in all LinearOpModes.
- * Our implementation here, though is a bit unusual: we've decided to put all the actual work
- * in the runSample() method rather than directly in runOpMode() itself. The reason we do that is
- * that in this sample we're changing the background color of the robot controller screen as the
- * OpMode runs, and we want to be able to *guarantee* that we restore it to something reasonable
- * and palatable when the OpMode ends. The simplest way to do that is to use a try...finally
- * block around the main, core logic, and an easy way to make that all clear was to separate
- * the former from the latter in separate methods.
- */
- @Override public void runOpMode() {
-
- // Get a reference to the RelativeLayout so we can later change the background
- // color of the Robot Controller app to match the hue detected by the RGB sensor.
- int relativeLayoutId = hardwareMap.appContext.getResources().getIdentifier("RelativeLayout", "id", hardwareMap.appContext.getPackageName());
- relativeLayout = ((Activity) hardwareMap.appContext).findViewById(relativeLayoutId);
-
- try {
- runSample(); // actually execute the sample
- } finally {
- // On the way out, *guarantee* that the background is reasonable. It doesn't actually start off
- // as pure white, but it's too much work to dig out what actually was used, and this is good
- // enough to at least make the screen reasonable again.
- // Set the panel back to the default color
- relativeLayout.post(new Runnable() {
- public void run() {
- relativeLayout.setBackgroundColor(Color.WHITE);
- }
- });
- }
- }
-
- protected void runSample() {
- // You can give the sensor a gain value, will be multiplied by the sensor's raw value before the
- // normalized color values are calculated. Color sensors (especially the REV Color Sensor V3)
- // can give very low values (depending on the lighting conditions), which only use a small part
- // of the 0-1 range that is available for the red, green, and blue values. In brighter conditions,
- // you should use a smaller gain than in dark conditions. If your gain is too high, all of the
- // colors will report at or near 1, and you won't be able to determine what color you are
- // actually looking at. For this reason, it's better to err on the side of a lower gain
- // (but always greater than or equal to 1).
- float gain = 2;
-
- // Once per loop, we will update this hsvValues array. The first element (0) will contain the
- // hue, the second element (1) will contain the saturation, and the third element (2) will
- // contain the value. See http://web.archive.org/web/20190311170843/https://infohost.nmt.edu/tcc/help/pubs/colortheory/web/hsv.html
- // for an explanation of HSV color.
- final float[] hsvValues = new float[3];
-
- // xButtonPreviouslyPressed and xButtonCurrentlyPressed keep track of the previous and current
- // state of the X button on the gamepad
- boolean xButtonPreviouslyPressed = false;
- boolean xButtonCurrentlyPressed = false;
-
- // Get a reference to our sensor object. It's recommended to use NormalizedColorSensor over
- // ColorSensor, because NormalizedColorSensor consistently gives values between 0 and 1, while
- // the values you get from ColorSensor are dependent on the specific sensor you're using.
- colorSensor = hardwareMap.get(NormalizedColorSensor.class, "sensor_color");
-
- // If possible, turn the light on in the beginning (it might already be on anyway,
- // we just make sure it is if we can).
- if (colorSensor instanceof SwitchableLight) {
- ((SwitchableLight)colorSensor).enableLight(true);
- }
-
- // Wait for the start button to be pressed.
- waitForStart();
-
- // Loop until we are asked to stop
- while (opModeIsActive()) {
- // Explain basic gain information via telemetry
- telemetry.addLine("Hold the A button on gamepad 1 to increase gain, or B to decrease it.\n");
- telemetry.addLine("Higher gain values mean that the sensor will report larger numbers for Red, Green, and Blue, and Value\n");
-
- // Update the gain value if either of the A or B gamepad buttons is being held
- if (gamepad1.a) {
- // Only increase the gain by a small amount, since this loop will occur multiple times per second.
- gain += 0.005;
- } else if (gamepad1.b && gain > 1) { // A gain of less than 1 will make the values smaller, which is not helpful.
- gain -= 0.005;
- }
-
- // Show the gain value via telemetry
- telemetry.addData("Gain", gain);
-
- // Tell the sensor our desired gain value (normally you would do this during initialization,
- // not during the loop)
- colorSensor.setGain(gain);
-
- // Check the status of the X button on the gamepad
- xButtonCurrentlyPressed = gamepad1.x;
-
- // If the button state is different than what it was, then act
- if (xButtonCurrentlyPressed != xButtonPreviouslyPressed) {
- // If the button is (now) down, then toggle the light
- if (xButtonCurrentlyPressed) {
- if (colorSensor instanceof SwitchableLight) {
- SwitchableLight light = (SwitchableLight)colorSensor;
- light.enableLight(!light.isLightOn());
- }
- }
- }
- xButtonPreviouslyPressed = xButtonCurrentlyPressed;
-
- // Get the normalized colors from the sensor
- NormalizedRGBA colors = colorSensor.getNormalizedColors();
-
- /* Use telemetry to display feedback on the driver station. We show the red, green, and blue
- * normalized values from the sensor (in the range of 0 to 1), as well as the equivalent
- * HSV (hue, saturation and value) values. See http://web.archive.org/web/20190311170843/https://infohost.nmt.edu/tcc/help/pubs/colortheory/web/hsv.html
- * for an explanation of HSV color. */
-
- // Update the hsvValues array by passing it to Color.colorToHSV()
- Color.colorToHSV(colors.toColor(), hsvValues);
-
- telemetry.addLine()
- .addData("Red", "%.3f", colors.red)
- .addData("Green", "%.3f", colors.green)
- .addData("Blue", "%.3f", colors.blue);
- telemetry.addLine()
- .addData("Hue", "%.3f", hsvValues[0])
- .addData("Saturation", "%.3f", hsvValues[1])
- .addData("Value", "%.3f", hsvValues[2]);
- telemetry.addData("Alpha", "%.3f", colors.alpha);
-
- /* If this color sensor also has a distance sensor, display the measured distance.
- * Note that the reported distance is only useful at very close range, and is impacted by
- * ambient light and surface reflectivity. */
- if (colorSensor instanceof DistanceSensor) {
- telemetry.addData("Distance (cm)", "%.3f", ((DistanceSensor) colorSensor).getDistance(DistanceUnit.CM));
- }
-
- telemetry.update();
-
- // Change the Robot Controller's background color to match the color detected by the color sensor.
- relativeLayout.post(new Runnable() {
- public void run() {
- relativeLayout.setBackgroundColor(Color.HSVToColor(hsvValues));
- }
- });
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorDigitalTouch.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorDigitalTouch.java
deleted file mode 100644
index 44c3ca9c..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorDigitalTouch.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Copyright (c) 2024 FIRST. 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 com.qualcomm.robotcore.hardware.DigitalChannel;
-
-/*
- * This OpMode demonstrates how to use a digital channel.
- *
- * The OpMode assumes that the digital channel is configured with a name of "digitalTouch".
- *
- * 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 = "Sensor: digital channel", group = "Sensor")
-@Disabled
-public class SensorDigitalTouch extends LinearOpMode {
- DigitalChannel digitalTouch; // Digital channel Object
-
- @Override
- public void runOpMode() {
-
- // get a reference to our touchSensor object.
- digitalTouch = hardwareMap.get(DigitalChannel.class, "digitalTouch");
-
- digitalTouch.setMode(DigitalChannel.Mode.INPUT);
- telemetry.addData("DigitalTouchSensorExample", "Press start to continue...");
- telemetry.update();
-
- // wait for the start button to be pressed.
- waitForStart();
-
- // while the OpMode is active, loop and read the digital channel.
- // Note we use opModeIsActive() as our loop condition because it is an interruptible method.
- while (opModeIsActive()) {
-
- // button is pressed if value returned is LOW or false.
- // send the info back to driver station using telemetry function.
- if (digitalTouch.getState() == false) {
- telemetry.addData("Button", "PRESSED");
- } else {
- telemetry.addData("Button", "NOT PRESSED");
- }
-
- telemetry.update();
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorHuskyLens.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorHuskyLens.java
deleted file mode 100644
index af7ca552..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorHuskyLens.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
-Copyright (c) 2023 FIRST
-
-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.dfrobot.HuskyLens;
-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.internal.system.Deadline;
-
-import java.util.concurrent.TimeUnit;
-
-/*
- * This OpMode illustrates how to use the DFRobot HuskyLens.
- *
- * The HuskyLens is a Vision Sensor with a built-in object detection model. It 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
- * 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
- * of objects by changing the algorithm. It assumes that the HuskyLens is configured with
- * a name of "huskylens".
- *
- * 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 = "Sensor: HuskyLens", group = "Sensor")
-@Disabled
-public class SensorHuskyLens extends LinearOpMode {
-
- private final int READ_PERIOD = 1;
-
- private HuskyLens huskyLens;
-
- @Override
- public void runOpMode()
- {
- huskyLens = hardwareMap.get(HuskyLens.class, "huskylens");
-
- /*
- * This sample rate limits the reads solely to allow a user time to observe
- * what is happening on the Driver Station telemetry. Typical applications
- * would not likely rate limit.
- */
- Deadline rateLimit = new Deadline(READ_PERIOD, TimeUnit.SECONDS);
-
- /*
- * Immediately expire so that the first time through we'll do the read.
- */
- rateLimit.expire();
-
- /*
- * Basic check to see if the device is alive and communicating. This is not
- * technically necessary here as the HuskyLens class does this in its
- * doInitialization() method which is called when the device is pulled out of
- * the hardware map. However, sometimes it's unclear why a device reports as
- * failing on initialization. In the case of this device, it's because the
- * call to knock() failed.
- */
- if (!huskyLens.knock()) {
- telemetry.addData(">>", "Problem communicating with " + huskyLens.getDeviceName());
- } else {
- telemetry.addData(">>", "Press start to continue");
- }
-
- /*
- * The device uses the concept of an algorithm to determine what types of
- * objects it will look for and/or what mode it is in. The algorithm may be
- * selected using the scroll wheel on the device, or via software as shown in
- * the call to selectAlgorithm().
- *
- * The SDK itself does not assume that the user wants a particular algorithm on
- * startup, and hence does not set an algorithm.
- *
- * 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
- * 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);
-
- telemetry.update();
- waitForStart();
-
- /*
- * Looking for AprilTags per the call to selectAlgorithm() above. A handy grid
- * for testing may be found at https://wiki.dfrobot.com/HUSKYLENS_V1.0_SKU_SEN0305_SEN0336#target_20.
- *
- * Note again that the device only recognizes the 36h11 family of tags out of the box.
- */
- while(opModeIsActive()) {
- if (!rateLimit.hasExpired()) {
- continue;
- }
- rateLimit.reset();
-
- /*
- * All algorithms, except for LINE_TRACKING, return a list of Blocks where a
- * Block represents the outline of a recognized object along with its ID number.
- * ID numbers allow you to identify what the device saw. See the HuskyLens documentation
- * referenced in the header comment above for more information on IDs and how to
- * assign them to objects.
- *
- * Returns an empty array if no objects are seen.
- */
- HuskyLens.Block[] blocks = huskyLens.blocks();
- telemetry.addData("Block count", blocks.length);
- for (int i = 0; i < blocks.length; i++) {
- 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();
- }
- }
-}
\ No newline at end of file
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUNonOrthogonal.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUNonOrthogonal.java
deleted file mode 100644
index 70bc8d4a..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUNonOrthogonal.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/* Copyright (c) 2022 FIRST. 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.rev.RevHubOrientationOnRobot;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.IMU;
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-import org.firstinspires.ftc.robotcore.external.navigation.AngularVelocity;
-import org.firstinspires.ftc.robotcore.external.navigation.Orientation;
-import org.firstinspires.ftc.robotcore.external.navigation.YawPitchRollAngles;
-
-import static com.qualcomm.hardware.rev.RevHubOrientationOnRobot.xyzOrientation;
-
-/*
- * This OpMode shows how to use the new universal IMU interface. This
- * interface may be used with the BNO055 IMU or the BHI260 IMU. It assumes that an IMU is configured
- * on the robot with the name "imu".
- *
- * The sample will display the current Yaw, Pitch and Roll of the robot.
- * With the correct orientation parameters selected, pitch/roll/yaw should act as follows:
- * Pitch value should INCREASE as the robot is tipped UP at the front. (Rotation about X)
- * Roll value should INCREASE as the robot is tipped UP at the left side. (Rotation about Y)
- * Yaw value should INCREASE as the robot is rotated Counter Clockwise. (Rotation about Z)
- *
- * The yaw can be reset (to zero) by pressing the Y button on the gamepad (Triangle on a PS4 controller)
- *
- * This specific sample DOES NOT assume that the Hub is mounted on one of the three orthogonal
- * 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
- * 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
- * that transform a "Default" Hub orientation into your desired orientation. That is what is
- * illustrated here.
- *
- * 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.
- *
- * Finally, edit this OpMode to use at least one angle around an axis to orient your Hub.
- */
-@TeleOp(name = "Sensor: IMU Non-Orthogonal", group = "Sensor")
-@Disabled // Comment this out to add to the OpMode list
-public class SensorIMUNonOrthogonal extends LinearOpMode
-{
- // The IMU sensor object
- IMU imu;
-
- //----------------------------------------------------------------------------------------------
- // Main logic
- //----------------------------------------------------------------------------------------------
-
- @Override public void runOpMode() throws InterruptedException {
-
- // Retrieve and initialize the IMU.
- // This sample expects the IMU to be in a REV Hub and named "imu".
- imu = hardwareMap.get(IMU.class, "imu");
-
- /* Define how the hub is mounted to the robot to get the correct Yaw, Pitch and Roll values.
- *
- * You can apply up to three axis rotations to orient your Hub according to how it's mounted on the robot.
- *
- * The starting point for these rotations is the "Default" Hub orientation, which is:
- * 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.
- *
- * 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.
- * 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
- * used for the results the IMU gives us. In the starting orientation, the Hub axes are
- * aligned with the Robot Coordinate System:
- *
- * X Axis: Starting at Center of Hub, pointing out towards I2C connectors
- * Y Axis: Starting at Center of Hub, pointing out towards USB connectors
- * Z Axis: Starting at Center of Hub, pointing Up through LOGO
- *
- * Positive rotation is defined by right-hand rule with thumb pointing in +ve direction on axis.
- *
- * Some examples.
- *
- * ----------------------------------------------------------------------------------------------------------------------------------
- * Example A) Assume that the hub is mounted on a sloped plate at the back of the robot, with the USB ports coming out the top of the hub.
- * The plate is tilted UP 60 degrees from horizontal.
- *
- * To get the "Default" hub into this configuration you would just need a single rotation.
- * 1) Rotate the Hub +60 degrees around the X axis to tilt up the front edge.
- * 2) No rotation around the Y or Z axes.
- *
- * So the X,Y,Z rotations would be 60,0,0
- *
- * ----------------------------------------------------------------------------------------------------------------------------------
- * Example B) Assume that the hub is laying flat on the chassis, but it has been twisted 30 degrees towards the right front wheel to make
- * the USB cable accessible.
- *
- * 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.
- * 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
- *
- * ----------------------------------------------------------------------------------------------------------------------------------
- * Example C) Assume that the hub is mounted on a vertical plate on the right side of the robot, with the Logo facing out, and the
- * Hub rotated so that the USB ports are facing down 30 degrees towards the back wheels of the robot.
- *
- * To get the "Default" hub into this configuration will require several rotations.
- * 1) Rotate the hub +90 degrees around the X axis to get it standing upright with the logo pointing backwards on the robot
- * 2) Next, rotate the hub +90 around the Y axis to get it facing to the right.
- * 3) Finally rotate the hub +120 degrees around the Z axis to take the USB ports from vertical to sloping down 30 degrees and
- * facing towards the back of the robot.
- *
- * So the X,Y,Z rotations would be 90,90,120
- */
-
- // The next three lines define the desired axis rotations.
- // To Do: EDIT these values to match YOUR mounting configuration.
- double xRotation = 0; // enter the desired X rotation angle here.
- double yRotation = 0; // enter the desired Y rotation angle here.
- double zRotation = 0; // enter the desired Z rotation angle here.
-
- Orientation hubRotation = xyzOrientation(xRotation, yRotation, zRotation);
-
- // Now initialize the IMU with this mounting orientation
- RevHubOrientationOnRobot orientationOnRobot = new RevHubOrientationOnRobot(hubRotation);
- imu.initialize(new IMU.Parameters(orientationOnRobot));
-
- // Loop and update the dashboard
- while (!isStopRequested()) {
- telemetry.addData("Hub orientation", "X=%.1f, Y=%.1f, Z=%.1f \n", xRotation, yRotation, zRotation);
-
- // Check to see if heading reset is requested
- if (gamepad1.y) {
- telemetry.addData("Yaw", "Resetting\n");
- imu.resetYaw();
- } else {
- telemetry.addData("Yaw", "Press Y (triangle) on Gamepad to reset\n");
- }
-
- // Retrieve Rotational Angles and Velocities
- YawPitchRollAngles orientation = imu.getRobotYawPitchRollAngles();
- AngularVelocity angularVelocity = imu.getRobotAngularVelocity(AngleUnit.DEGREES);
-
- telemetry.addData("Yaw (Z)", "%.2f Deg. (Heading)", orientation.getYaw(AngleUnit.DEGREES));
- telemetry.addData("Pitch (X)", "%.2f Deg.", orientation.getPitch(AngleUnit.DEGREES));
- telemetry.addData("Roll (Y)", "%.2f Deg.\n", orientation.getRoll(AngleUnit.DEGREES));
- telemetry.addData("Yaw (Z) velocity", "%.2f Deg/Sec", angularVelocity.zRotationRate);
- telemetry.addData("Pitch (X) velocity", "%.2f Deg/Sec", angularVelocity.xRotationRate);
- telemetry.addData("Roll (Y) velocity", "%.2f Deg/Sec", angularVelocity.yRotationRate);
- telemetry.update();
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUOrthogonal.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUOrthogonal.java
deleted file mode 100644
index af4c2028..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUOrthogonal.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/* Copyright (c) 2022 FIRST. 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.rev.RevHubOrientationOnRobot;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.IMU;
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-import org.firstinspires.ftc.robotcore.external.navigation.AngularVelocity;
-import org.firstinspires.ftc.robotcore.external.navigation.YawPitchRollAngles;
-
-/*
- * This OpMode shows how to use the new universal IMU interface. This
- * interface may be used with the BNO055 IMU or the BHI260 IMU. It assumes that an IMU is configured
- * on the robot with the name "imu".
- *
- * The sample will display the current Yaw, Pitch and Roll of the robot.
- * With the correct orientation parameters selected, pitch/roll/yaw should act as follows:
- * Pitch value should INCREASE as the robot is tipped UP at the front. (Rotation about X)
- * Roll value should INCREASE as the robot is tipped UP at the left side. (Rotation about Y)
- * Yaw value should INCREASE as the robot is rotated Counter Clockwise. (Rotation about Z)
- *
- * The yaw can be reset (to zero) by pressing the Y button on the gamepad (Triangle on a PS4 controller)
- *
- * This specific sample assumes that the Hub is mounted on one of the three orthogonal planes
- * (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
- * the alternative SensorIMUNonOrthogonal sample in this folder.
- *
- * This "Orthogonal" requirement means that:
- *
- * 1) The Logo printed on the top of the Hub can ONLY be pointing in one of six directions:
- * FORWARD, BACKWARD, UP, DOWN, LEFT and RIGHT.
- *
- * 2) The USB ports can only be pointing in one of the same six directions:
- * FORWARD, BACKWARD, UP, DOWN, LEFT and RIGHT.
- *
- * So, To fully define how your Hub is mounted to the robot, you must simply specify:
- * logoFacingDirection
- * usbFacingDirection
- *
- * 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.
- *
- * Finally, choose the two correct parameters to define how your Hub is mounted and edit this OpMode
- * to use those parameters.
- */
-@TeleOp(name = "Sensor: IMU Orthogonal", group = "Sensor")
-@Disabled // Comment this out to add to the OpMode list
-public class SensorIMUOrthogonal extends LinearOpMode
-{
- // The IMU sensor object
- IMU imu;
-
- //----------------------------------------------------------------------------------------------
- // Main logic
- //----------------------------------------------------------------------------------------------
-
- @Override public void runOpMode() throws InterruptedException {
-
- // Retrieve and initialize the IMU.
- // This sample expects the IMU to be in a REV Hub and named "imu".
- imu = hardwareMap.get(IMU.class, "imu");
-
- /* Define how the hub is mounted on the robot to get the correct Yaw, Pitch and Roll values.
- *
- * Two input parameters are required to fully specify the Orientation.
- * 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.
- * 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 Default Orientation (shown) is when a hub is mounted horizontally with the printed logo pointing UP and the USB port pointing FORWARD.
- *
- * To Do: EDIT these two lines to match YOUR mounting configuration.
- */
- RevHubOrientationOnRobot.LogoFacingDirection logoDirection = RevHubOrientationOnRobot.LogoFacingDirection.UP;
- RevHubOrientationOnRobot.UsbFacingDirection usbDirection = RevHubOrientationOnRobot.UsbFacingDirection.FORWARD;
-
- RevHubOrientationOnRobot orientationOnRobot = new RevHubOrientationOnRobot(logoDirection, usbDirection);
-
- // Now initialize the IMU with this mounting orientation
- // Note: if you choose two conflicting directions, this initialization will cause a code exception.
- imu.initialize(new IMU.Parameters(orientationOnRobot));
-
- // Loop and update the dashboard
- while (!isStopRequested()) {
-
- telemetry.addData("Hub orientation", "Logo=%s USB=%s\n ", logoDirection, usbDirection);
-
- // Check to see if heading reset is requested
- if (gamepad1.y) {
- telemetry.addData("Yaw", "Resetting\n");
- imu.resetYaw();
- } else {
- telemetry.addData("Yaw", "Press Y (triangle) on Gamepad to reset\n");
- }
-
- // Retrieve Rotational Angles and Velocities
- YawPitchRollAngles orientation = imu.getRobotYawPitchRollAngles();
- AngularVelocity angularVelocity = imu.getRobotAngularVelocity(AngleUnit.DEGREES);
-
- telemetry.addData("Yaw (Z)", "%.2f Deg. (Heading)", orientation.getYaw(AngleUnit.DEGREES));
- telemetry.addData("Pitch (X)", "%.2f Deg.", orientation.getPitch(AngleUnit.DEGREES));
- telemetry.addData("Roll (Y)", "%.2f Deg.\n", orientation.getRoll(AngleUnit.DEGREES));
- telemetry.addData("Yaw (Z) velocity", "%.2f Deg/Sec", angularVelocity.zRotationRate);
- telemetry.addData("Pitch (X) velocity", "%.2f Deg/Sec", angularVelocity.xRotationRate);
- telemetry.addData("Roll (Y) velocity", "%.2f Deg/Sec", angularVelocity.yRotationRate);
- telemetry.update();
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorKLNavxMicro.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorKLNavxMicro.java
deleted file mode 100644
index ccc945ff..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorKLNavxMicro.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.kauailabs.NavxMicroNavigationSensor;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.Gyroscope;
-import com.qualcomm.robotcore.hardware.IntegratingGyroscope;
-import com.qualcomm.robotcore.util.ElapsedTime;
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-import org.firstinspires.ftc.robotcore.external.navigation.AngularVelocity;
-import org.firstinspires.ftc.robotcore.external.navigation.AxesOrder;
-import org.firstinspires.ftc.robotcore.external.navigation.AxesReference;
-import org.firstinspires.ftc.robotcore.external.navigation.Orientation;
-
-/*
- * This OpMode shows how to use Kauai Labs navX Micro Robotics Navigation
- * Sensor. It assumes that the sensor is configured with a name of "navx".
- *
- * 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 = "Sensor: KL navX Micro", group = "Sensor")
-@Disabled
-public class SensorKLNavxMicro extends LinearOpMode {
-
- /** In this sample, for illustration purposes we use two interfaces on the one gyro object.
- * That's likely atypical: you'll probably use one or the other in any given situation,
- * depending on what you're trying to do. {@link IntegratingGyroscope} (and it's base interface,
- * {@link Gyroscope}) are common interfaces supported by possibly several different gyro
- * implementations. {@link NavxMicroNavigationSensor}, by contrast, provides functionality that
- * is unique to the navX Micro sensor.
- */
- IntegratingGyroscope gyro;
- NavxMicroNavigationSensor navxMicro;
-
- // A timer helps provide feedback while calibration is taking place
- ElapsedTime timer = new ElapsedTime();
-
- @Override public void runOpMode() throws InterruptedException {
- // Get a reference to a Modern Robotics GyroSensor object. We use several interfaces
- // on this object to illustrate which interfaces support which functionality.
- navxMicro = hardwareMap.get(NavxMicroNavigationSensor.class, "navx");
- gyro = (IntegratingGyroscope)navxMicro;
- // If you're only interested int the IntegratingGyroscope interface, the following will suffice.
- // gyro = hardwareMap.get(IntegratingGyroscope.class, "navx");
-
- // The gyro automatically starts calibrating. This takes a few seconds.
- telemetry.log().add("Gyro Calibrating. Do Not Move!");
-
- // Wait until the gyro calibration is complete
- timer.reset();
- while (navxMicro.isCalibrating()) {
- telemetry.addData("calibrating", "%s", Math.round(timer.seconds())%2==0 ? "|.." : "..|");
- telemetry.update();
- Thread.sleep(50);
- }
- telemetry.log().clear(); telemetry.log().add("Gyro Calibrated. Press Start.");
- telemetry.clear(); telemetry.update();
-
- // Wait for the start button to be pressed
- waitForStart();
- telemetry.log().clear();
-
- while (opModeIsActive()) {
-
- // Read dimensionalized data from the gyro. This gyro can report angular velocities
- // about all three axes. Additionally, it internally integrates the Z axis to
- // be able to report an absolute angular Z orientation.
- AngularVelocity rates = gyro.getAngularVelocity(AngleUnit.DEGREES);
- Orientation angles = gyro.getAngularOrientation(AxesReference.INTRINSIC, AxesOrder.ZYX, AngleUnit.DEGREES);
-
- telemetry.addLine()
- .addData("dx", formatRate(rates.xRotationRate))
- .addData("dy", formatRate(rates.yRotationRate))
- .addData("dz", "%s deg/s", formatRate(rates.zRotationRate));
-
- telemetry.addLine()
- .addData("heading", formatAngle(angles.angleUnit, angles.firstAngle))
- .addData("roll", formatAngle(angles.angleUnit, angles.secondAngle))
- .addData("pitch", "%s deg", formatAngle(angles.angleUnit, angles.thirdAngle));
- telemetry.update();
-
- idle(); // Always call idle() at the bottom of your while(opModeIsActive()) loop
- }
- }
-
- String formatRate(float rate) {
- return String.format("%.3f", rate);
- }
-
- String formatAngle(AngleUnit angleUnit, double angle) {
- return formatDegrees(AngleUnit.DEGREES.fromUnit(angleUnit, angle));
- }
-
- String formatDegrees(double degrees){
- return String.format("%.1f", AngleUnit.DEGREES.normalize(degrees));
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorLimelight3A.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorLimelight3A.java
deleted file mode 100644
index 6c1f702a..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorLimelight3A.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
-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 Limelight
- *
- * 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 barcodeResults = result.getBarcodeResults();
- for (LLResultTypes.BarcodeResult br : barcodeResults) {
- telemetry.addData("Barcode", "Data: %s", br.getData());
- }
-
- // Access classifier results
- List classifierResults = result.getClassifierResults();
- for (LLResultTypes.ClassifierResult cr : classifierResults) {
- telemetry.addData("Classifier", "Class: %s, Confidence: %.2f", cr.getClassName(), cr.getConfidence());
- }
-
- // Access detector results
- List detectorResults = result.getDetectorResults();
- for (LLResultTypes.DetectorResult dr : detectorResults) {
- telemetry.addData("Detector", "Class: %s, Area: %.2f", dr.getClassName(), dr.getTargetArea());
- }
-
- // Access fiducial results
- List 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 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();
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRColor.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRColor.java
deleted file mode 100644
index 32b37e09..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRColor.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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 android.app.Activity;
-import android.graphics.Color;
-import android.view.View;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.ColorSensor;
-
-/*
- *
- * This OpMode that shows how to use
- * a Modern Robotics Color Sensor.
- *
- * The OpMode assumes that the color sensor
- * is configured with a name of "sensor_color".
- *
- * You can use the X button on gamepad1 to toggle the LED on and off.
- *
- * 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 = "Sensor: MR Color", group = "Sensor")
-@Disabled
-public class SensorMRColor extends LinearOpMode {
-
- ColorSensor colorSensor; // Hardware Device Object
-
-
- @Override
- public void runOpMode() {
-
- // hsvValues is an array that will hold the hue, saturation, and value information.
- float hsvValues[] = {0F,0F,0F};
-
- // values is a reference to the hsvValues array.
- final float values[] = hsvValues;
-
- // get a reference to the RelativeLayout so we can change the background
- // color of the Robot Controller app to match the hue detected by the RGB sensor.
- int relativeLayoutId = hardwareMap.appContext.getResources().getIdentifier("RelativeLayout", "id", hardwareMap.appContext.getPackageName());
- final View relativeLayout = ((Activity) hardwareMap.appContext).findViewById(relativeLayoutId);
-
- // bPrevState and bCurrState represent the previous and current state of the button.
- boolean bPrevState = false;
- boolean bCurrState = false;
-
- // bLedOn represents the state of the LED.
- boolean bLedOn = true;
-
- // get a reference to our ColorSensor object.
- colorSensor = hardwareMap.get(ColorSensor.class, "sensor_color");
-
- // Set the LED in the beginning
- colorSensor.enableLed(bLedOn);
-
- // wait for the start button to be pressed.
- waitForStart();
-
- // while the OpMode is active, loop and read the RGB data.
- // Note we use opModeIsActive() as our loop condition because it is an interruptible method.
- while (opModeIsActive()) {
-
- // check the status of the x button on either gamepad.
- bCurrState = gamepad1.x;
-
- // check for button state transitions.
- if (bCurrState && (bCurrState != bPrevState)) {
-
- // button is transitioning to a pressed state. So Toggle LED
- bLedOn = !bLedOn;
- colorSensor.enableLed(bLedOn);
- }
-
- // update previous state variable.
- bPrevState = bCurrState;
-
- // convert the RGB values to HSV values.
- Color.RGBToHSV(colorSensor.red() * 8, colorSensor.green() * 8, colorSensor.blue() * 8, hsvValues);
-
- // send the info back to driver station using telemetry function.
- telemetry.addData("LED", bLedOn ? "On" : "Off");
- telemetry.addData("Clear", colorSensor.alpha());
- telemetry.addData("Red ", colorSensor.red());
- telemetry.addData("Green", colorSensor.green());
- telemetry.addData("Blue ", colorSensor.blue());
- telemetry.addData("Hue", hsvValues[0]);
-
- // change the background color to match the color detected by the RGB sensor.
- // pass a reference to the hue, saturation, and value array as an argument
- // to the HSVToColor method.
- relativeLayout.post(new Runnable() {
- public void run() {
- relativeLayout.setBackgroundColor(Color.HSVToColor(0xff, values));
- }
- });
-
- telemetry.update();
- }
-
- // Set the panel back to the default color
- relativeLayout.post(new Runnable() {
- public void run() {
- relativeLayout.setBackgroundColor(Color.WHITE);
- }
- });
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRGyro.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRGyro.java
deleted file mode 100644
index 91c0062e..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRGyro.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.modernrobotics.ModernRoboticsI2cGyro;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.IntegratingGyroscope;
-import com.qualcomm.robotcore.util.ElapsedTime;
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-import org.firstinspires.ftc.robotcore.external.navigation.AngularVelocity;
-import org.firstinspires.ftc.robotcore.external.navigation.AxesOrder;
-import org.firstinspires.ftc.robotcore.external.navigation.AxesReference;
-
-/*
- * This OpMode shows how to use the Modern Robotics Gyro.
- *
- * The OpMode assumes that the gyro sensor is attached to a Device Interface Module
- * I2C channel and is configured with a name of "gyro".
- *
- * 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 = "Sensor: MR Gyro", group = "Sensor")
-@Disabled
-public class SensorMRGyro extends LinearOpMode {
-
- /* In this sample, for illustration purposes we use two interfaces on the one gyro object.
- * That's likely atypical: you'll probably use one or the other in any given situation,
- * depending on what you're trying to do. {@link IntegratingGyroscope} (and it's base interface,
- * {@link Gyroscope}) are common interfaces supported by possibly several different gyro
- * implementations. {@link ModernRoboticsI2cGyro}, by contrast, provides functionality that
- * is unique to the Modern Robotics gyro sensor.
- */
- IntegratingGyroscope gyro;
- ModernRoboticsI2cGyro modernRoboticsI2cGyro;
-
- // A timer helps provide feedback while calibration is taking place
- ElapsedTime timer = new ElapsedTime();
-
- @Override
- public void runOpMode() {
-
- boolean lastResetState = false;
- boolean curResetState = false;
-
- // Get a reference to a Modern Robotics gyro object. We use several interfaces
- // on this object to illustrate which interfaces support which functionality.
- modernRoboticsI2cGyro = hardwareMap.get(ModernRoboticsI2cGyro.class, "gyro");
- gyro = (IntegratingGyroscope)modernRoboticsI2cGyro;
- // If you're only interested int the IntegratingGyroscope interface, the following will suffice.
- // gyro = hardwareMap.get(IntegratingGyroscope.class, "gyro");
- // A similar approach will work for the Gyroscope interface, if that's all you need.
-
- // Start calibrating the gyro. This takes a few seconds and is worth performing
- // during the initialization phase at the start of each OpMode.
- telemetry.log().add("Gyro Calibrating. Do Not Move!");
- modernRoboticsI2cGyro.calibrate();
-
- // Wait until the gyro calibration is complete
- timer.reset();
- while (!isStopRequested() && modernRoboticsI2cGyro.isCalibrating()) {
- telemetry.addData("calibrating", "%s", Math.round(timer.seconds())%2==0 ? "|.." : "..|");
- telemetry.update();
- sleep(50);
- }
-
- telemetry.log().clear(); telemetry.log().add("Gyro Calibrated. Press Start.");
- telemetry.clear(); telemetry.update();
-
- // Wait for the start button to be pressed
- waitForStart();
- telemetry.log().clear();
- telemetry.log().add("Press A & B to reset heading");
-
- // Loop until we're asked to stop
- while (opModeIsActive()) {
-
- // If the A and B buttons are pressed just now, reset Z heading.
- curResetState = (gamepad1.a && gamepad1.b);
- if (curResetState && !lastResetState) {
- modernRoboticsI2cGyro.resetZAxisIntegrator();
- }
- lastResetState = curResetState;
-
- // The raw() methods report the angular rate of change about each of the
- // three axes directly as reported by the underlying sensor IC.
- int rawX = modernRoboticsI2cGyro.rawX();
- int rawY = modernRoboticsI2cGyro.rawY();
- int rawZ = modernRoboticsI2cGyro.rawZ();
- int heading = modernRoboticsI2cGyro.getHeading();
- int integratedZ = modernRoboticsI2cGyro.getIntegratedZValue();
-
- // Read dimensionalized data from the gyro. This gyro can report angular velocities
- // about all three axes. Additionally, it internally integrates the Z axis to
- // be able to report an absolute angular Z orientation.
- AngularVelocity rates = gyro.getAngularVelocity(AngleUnit.DEGREES);
- float zAngle = gyro.getAngularOrientation(AxesReference.INTRINSIC, AxesOrder.ZYX, AngleUnit.DEGREES).firstAngle;
-
- // Read administrative information from the gyro
- int zAxisOffset = modernRoboticsI2cGyro.getZAxisOffset();
- int zAxisScalingCoefficient = modernRoboticsI2cGyro.getZAxisScalingCoefficient();
-
- telemetry.addLine()
- .addData("dx", formatRate(rates.xRotationRate))
- .addData("dy", formatRate(rates.yRotationRate))
- .addData("dz", "%s deg/s", formatRate(rates.zRotationRate));
- telemetry.addData("angle", "%s deg", formatFloat(zAngle));
- telemetry.addData("heading", "%3d deg", heading);
- telemetry.addData("integrated Z", "%3d", integratedZ);
- telemetry.addLine()
- .addData("rawX", formatRaw(rawX))
- .addData("rawY", formatRaw(rawY))
- .addData("rawZ", formatRaw(rawZ));
- telemetry.addLine().addData("z offset", zAxisOffset).addData("z coeff", zAxisScalingCoefficient);
- telemetry.update();
- }
- }
-
- String formatRaw(int rawValue) {
- return String.format("%d", rawValue);
- }
-
- String formatRate(float rate) {
- return String.format("%.3f", rate);
- }
-
- String formatFloat(float rate) {
- return String.format("%.3f", rate);
- }
-
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMROpticalDistance.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMROpticalDistance.java
deleted file mode 100644
index 6d2dfa39..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMROpticalDistance.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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 com.qualcomm.robotcore.hardware.OpticalDistanceSensor;
-
-/*
- * This OpMode shows how to use a Modern Robotics Optical Distance Sensor
- * It assumes that the ODS sensor is configured with a name of "sensor_ods".
- *
- * 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 = "Sensor: MR ODS", group = "Sensor")
-@Disabled
-public class SensorMROpticalDistance extends LinearOpMode {
-
- OpticalDistanceSensor odsSensor; // Hardware Device Object
-
- @Override
- public void runOpMode() {
-
- // get a reference to our Light Sensor object.
- odsSensor = hardwareMap.get(OpticalDistanceSensor.class, "sensor_ods");
-
- // wait for the start button to be pressed.
- waitForStart();
-
- // while the OpMode is active, loop and read the light levels.
- // Note we use opModeIsActive() as our loop condition because it is an interruptible method.
- while (opModeIsActive()) {
-
- // send the info back to driver station using telemetry function.
- telemetry.addData("Raw", odsSensor.getRawLightDetected());
- telemetry.addData("Normal", odsSensor.getLightDetected());
-
- telemetry.update();
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRRangeSensor.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRRangeSensor.java
deleted file mode 100644
index 2039ef97..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRRangeSensor.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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.modernrobotics.ModernRoboticsI2cRangeSensor;
-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.DistanceUnit;
-
-/*
- * This OpMode illustrates how to use the Modern Robotics Range Sensor.
- *
- * The OpMode assumes that the range sensor is configured with a name of "sensor_range".
- *
- * 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
- *
- * @see MR Range Sensor
- */
-@TeleOp(name = "Sensor: MR range sensor", group = "Sensor")
-@Disabled // comment out or remove this line to enable this OpMode
-public class SensorMRRangeSensor extends LinearOpMode {
-
- ModernRoboticsI2cRangeSensor rangeSensor;
-
- @Override public void runOpMode() {
-
- // get a reference to our compass
- rangeSensor = hardwareMap.get(ModernRoboticsI2cRangeSensor.class, "sensor_range");
-
- // wait for the start button to be pressed
- waitForStart();
-
- while (opModeIsActive()) {
- telemetry.addData("raw ultrasonic", rangeSensor.rawUltrasonic());
- telemetry.addData("raw optical", rangeSensor.rawOptical());
- telemetry.addData("cm optical", "%.2f cm", rangeSensor.cmOptical());
- telemetry.addData("cm", "%.2f cm", rangeSensor.getDistance(DistanceUnit.CM));
- telemetry.update();
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorOctoQuad.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorOctoQuad.java
deleted file mode 100644
index 81548216..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorOctoQuad.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (c) 2024 DigitalChickenLabs
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.firstinspires.ftc.robotcontroller.external.samples;
-
-import com.qualcomm.hardware.digitalchickenlabs.OctoQuad;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import org.firstinspires.ftc.robotcore.external.Telemetry;
-
-/*
- * This OpMode illustrates how to use the DigitalChickenLabs OctoQuad Quadrature Encoder & Pulse Width Interface Module
- *
- * The OctoQuad has 8 input channels that can used to read either Relative Quadrature Encoders or Pulse-Width Absolute Encoder inputs.
- * Relative Quadrature encoders are found on most FTC motors, and some stand-alone position sensors like the REV Thru-Bore encoder.
- * Pulse-Width encoders are less common. The REV Thru-Bore encoder can provide its absolute position via a variable pulse width,
- * as can several sonar rangefinders such as the MaxBotix MB1000 series.
- *
- * This basic sample shows how an OctoQuad can be used to read the position three Odometry pods fitted
- * with REV Thru-Bore encoders. For a more advanced example showing additional OctoQuad capabilities, see the SensorOctoQuadAdv sample.
- *
- * This OpMode assumes that the OctoQuad is attached to an I2C interface named "octoquad" in the robot configuration.
- *
- * The code assumes the first three OctoQuad inputs are connected as follows
- * - Chan 0: for measuring forward motion on the left side of the robot.
- * - Chan 1: for measuring forward motion on the right side of the robot.
- * - Chan 2: for measuring Lateral (strafing) motion.
- *
- * The encoder values may be reset to zero by pressing the X (left most) button on Gamepad 1.
- *
- * This sample does not show how to interpret these readings, just how to obtain and display them.
- *
- * 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
- *
- * See the sensor's product page: https://www.tindie.com/products/35114/
- */
-@TeleOp(name = "OctoQuad Basic", group="OctoQuad")
-@Disabled
-public class SensorOctoQuad extends LinearOpMode {
-
- // 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_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)
-
- // Declare the OctoQuad object and members to store encoder positions and velocities
- private OctoQuad octoquad;
-
- private int posLeft;
- private int posRight;
- private int posPerp;
-
- /**
- * This function is executed when this OpMode is selected from the Driver Station.
- */
- @Override
- public void runOpMode() {
-
- // Connect to OctoQuad by referring to its name in the Robot Configuration.
- octoquad = hardwareMap.get(OctoQuad.class, "octoquad");
-
- // Read the Firmware Revision number from the OctoQuad and display it as telemetry.
- telemetry.addData("OctoQuad Firmware Version ", octoquad.getFirmwareVersion());
-
- // Reverse the count-direction of any encoder that is not what you require.
- // 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_RIGHT, OctoQuad.EncoderDirection.FORWARD);
- octoquad.setSingleEncoderDirection(ODO_PERP, OctoQuad.EncoderDirection.FORWARD);
-
- // Any changes that are made should be saved in FLASH just in case there is a sensor power glitch.
- octoquad.saveParametersToFlash();
-
- telemetry.addLine("\nPress START to read encoder values");
- telemetry.update();
-
- waitForStart();
-
- // Configure the telemetry for optimal display of data.
- telemetry.setDisplayFormat(Telemetry.DisplayFormat.MONOSPACE);
- telemetry.setMsTransmissionInterval(50);
-
- // Set all the encoder inputs to zero.
- octoquad.resetAllPositions();
-
- // Loop while displaying the odometry pod positions.
- while (opModeIsActive()) {
- telemetry.addData(">", "Press X to Reset Encoders\n");
-
- // Check for X button to reset encoders.
- if (gamepad1.x) {
- // Reset the position of all encoders to zero.
- octoquad.resetAllPositions();
- }
-
- // Read all the encoder data. Load into local members.
- readOdometryPods();
-
- // Display the values.
- telemetry.addData("Left ", "%8d counts", posLeft);
- telemetry.addData("Right", "%8d counts", posRight);
- telemetry.addData("Perp ", "%8d counts", posPerp);
- telemetry.update();
- }
- }
-
- private void readOdometryPods() {
- // For best performance, we should only perform ONE transaction with the OctoQuad each cycle.
- // Since this example only needs to read positions from a few channels, we could use either
- // readPositionRange(idxFirst, idxLast) to get a select number of sequential channels
- // or
- // 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, we will read all of the encoder positions, and then pick out the ones we need.
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorOctoQuadAdv.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorOctoQuadAdv.java
deleted file mode 100644
index 2e807ce0..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorOctoQuadAdv.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright (c) 2024 DigitalChickenLabs
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.firstinspires.ftc.robotcontroller.external.samples;
-
-import com.qualcomm.hardware.digitalchickenlabs.OctoQuad;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.util.ElapsedTime;
-import com.qualcomm.robotcore.util.MovingStatistics;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-
-
-import org.firstinspires.ftc.robotcore.external.Telemetry;
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/*
- * This OpMode illustrates how to use advanced features of the DigitalChickenLabs OctoQuad Quadrature Encoder & Pulse Width Interface Module
- *
- * The OctoQuad has 8 input channels that can used to read either Quadrature Encoder signals (like with most FTC motors)
- * or Pulse-Width style Absolute Encoder inputs (eg: REV Through Bore encoder pulse width output).
- *
- * This OpMode illustrates several of the more advanced features of an OctoQuad, including Pulse Width measurement and velocity measurement.
- * For a more basic OpMode just showing how to read encoder inputs, see the SensorOctoQuad sample.
- *
- * This OpMode assumes that the OctoQuad is attached to an I2C interface named "octoquad" in the robot configuration.
- *
- * One system that requires a lot of encoder inputs is a Swerve Drive system.
- * Such a drive requires two encoders per drive module: one for position & velocity of the Drive motor/wheel, and one for position/angle of the Steering motor.
- * The Drive motor usually requires a quadrature encoder, and the Steering motor requires an Absolute encoder.
- * This quantity and combination of encoder inputs is a challenge, but a single OctoQuad could be used to read them all.
- *
- * This sample will configure an OctoQuad for a swerve drive, as follows
- * - Configure 4 Relative Quadrature Encoder inputs and 4 Absolute Pulse-Width Encoder inputs
- * - Configure a velocity sample interval of 25 mSec
- * - Configure a pulse width input range of 1-1024 uSec for a REV Through Bore Encoder's Absolute Pulse output.
- *
- * An OctoSwerveDrive class will be created to initialize the OctoQuad, and manage the 4 swerve modules.
- * An OctoSwerveModule class will be created to configure and read a single swerve module.
- *
- * Wiring:
- * The OctoQuad will be configured to accept Quadrature encoders on the first four channels and Absolute (pulse width) encoders on the last four channels.
- *
- * The standard 4-pin to 4-pin cable can be used to connect each Driver Motor encoder to the OctoQuad. (channels 0-3)
- *
- * A modified version of the REV 6-4 pin cable (shipped with the encoder) connects the steering encoder to the OctoQuad. (channels 4-7)
- * To connect the Absolute position signal from a REV Thru-Bore encoder to the OctoQuad, the Provided 6-pin to 4-pin cable will need to be modified.
- * At the 6-pin connector end, move the yellow wire from its initial pin-3 position to the ABS pin-5 position. This can be done easily
- * by using a small flathead screwdriver to lift the small white tab holding the metal wire crimp in place and gently pulling the wire out.
- * See the OctoSwerveDrive() constructor below for the correct wheel/channel assignment.
- *
- * 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
- *
- * 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.
- *
- * See the sensor's product page: https://www.tindie.com/products/35114/
- */
-@TeleOp(name="OctoQuad Advanced", group="OctoQuad")
-@Disabled
-public class SensorOctoQuadAdv extends LinearOpMode {
-
- @Override
- public void runOpMode() throws InterruptedException {
- // Connect to the OctoQuad by looking up its name in the hardwareMap.
- OctoQuad octoquad = hardwareMap.get(OctoQuad.class, "octoquad");
-
- // Create the interface for the Swerve Drive Encoders
- OctoSwerveDrive octoSwerveDrive = new OctoSwerveDrive(octoquad);
-
- // Display the OctoQuad firmware revision
- telemetry.addLine("OctoQuad Firmware v" + octoquad.getFirmwareVersion());
- telemetry.addLine("\nPress START to read encoder values");
- telemetry.update();
-
- waitForStart();
-
- // Configure the telemetry for optimal display of data.
- telemetry.setDisplayFormat(Telemetry.DisplayFormat.MONOSPACE);
- telemetry.setMsTransmissionInterval(50);
-
- // Run stats to determine cycle times.
- MovingStatistics avgTime = new MovingStatistics(100);
- ElapsedTime elapsedTime = new ElapsedTime();
-
- while (opModeIsActive()) {
- telemetry.addData(">", "Press X to Reset Encoders\n");
-
- if(gamepad1.x) {
- octoquad.resetAllPositions();
- }
-
- // read all the swerve drive encoders and update positions and velocities.
- octoSwerveDrive.updateModules();
- octoSwerveDrive.show(telemetry);
-
- // Update cycle time stats
- avgTime.add(elapsedTime.nanoseconds());
- elapsedTime.reset();
-
- telemetry.addData("Loop time", "%.1f mS", avgTime.getMean()/1000000);
- telemetry.update();
- }
- }
-}
-
-// ============================ Internal (Inner) Classes =============================
-
-/***
- * OctoSwerveDrive class manages 4 Swerve Modules
- * - Performs general OctoQuad initialization
- * - Creates 4 module classes, one for each swerve module
- * - Updates swerve drive status by reading all data from OctoQuad and Updating each module
- * - Displays all swerve drive data as telemetry
- */
-class OctoSwerveDrive {
-
- private final OctoQuad octoquad;
- private final List allModules = new ArrayList<>();
-
- // members to hold encoder data for each module.
- public final OctoSwerveModule LeftFront;
- public final OctoSwerveModule RightFront;
- public final OctoSwerveModule LeftBack;
- public final OctoSwerveModule RightBack;
-
- // Prepare an object to hold an entire OctoQuad encoder readable register bank (pos and vel)
- private final OctoQuad.EncoderDataBlock encoderDataBlock = new OctoQuad.EncoderDataBlock();
-
- public OctoSwerveDrive(OctoQuad octoquad) {
- this.octoquad = octoquad;
-
- // Clear out all prior settings and encoder data before setting up desired configuration
- octoquad.resetEverything();
-
- // Assume first 4 channels are relative encoders and the next 4 are absolute encoders
- octoquad.setChannelBankConfig(OctoQuad.ChannelBankConfig.BANK1_QUADRATURE_BANK2_PULSE_WIDTH);
-
- // Create the four OctoSwerveModules, and add them to a 'list' for easier reference.
-
- // Note: The wheel/channel order is set here. Ensure your encoder cables match.
- //
- // Note: The angleOffset must be set for each module so a forward facing wheel shows a steer angle of 0 degrees.
- // The process for determining the correct angleOffsets is as follows:
- // 1) Set all the angleValues (below) to zero then build and deploy the code.
- // 2) Physically rotate all the swerve drives so the wheels are facing forward in the desired 0 degree position
- // 3) Run the OpMode, view the telemetry and record the "Degrees" value for each module.
- // 4) Update the code by entering the recorded Degrees value for each module as the angleOffset (last) parameter in the lines below.
- //
- // Rebuild and deploy the new code. Verify that the telemetry now indicates 0 degrees when the wheels are facing forward.
- // Also verify that the correct module values change appropriately when you manually spin (drive) and rotate (steer) a wheel.
-
- allModules.add(LeftFront = new OctoSwerveModule(octoquad, "LF ",0,0));// Drive = 0, Steer = 4
- allModules.add(RightFront = new OctoSwerveModule(octoquad, "RF ",1,0));// Drive = 1, Steer = 5
- allModules.add(LeftBack = new OctoSwerveModule(octoquad, "LB ",2,0));// Drive = 2, Steer = 6
- allModules.add(RightBack = new OctoSwerveModule(octoquad, "RB ",3,0));// Drive = 3, Steer = 7
-
- // now make sure the settings persist through any power glitches.
- octoquad.saveParametersToFlash();
- }
-
- /**
- * Updates all 4 swerve modules
- */
- public void updateModules() {
- // Read full OctoQuad data block and then pass DataBlock to each swerve module to update themselves.
- octoquad.readAllEncoderData(encoderDataBlock);
- for (OctoSwerveModule module : allModules) {
- module.updateModule(encoderDataBlock);
- }
- }
-
- /**
- * Generate telemetry data for all modules.
- * @param telemetry OpMode Telemetry object
- */
- public void show(Telemetry telemetry) {
- // create general header block and then have each module add its own telemetry
- telemetry.addData("pos", " Count CPS Degree DPS");
- for (OctoSwerveModule module : allModules) {
- module.show(telemetry);
- }
- }
-}
-
-/***
- * The OctoSwerveModule class manages a single swerve module
- */
-class OctoSwerveModule {
-
- public double driveCounts;
- public double driveCountsPerSec;
- public double steerDegrees;
- public double steerDegreesPerSec;
-
- private final String name;
- private final int channel;
- private final double angleOffset;
- private final double steerDirMult;
-
- private static final int VELOCITY_SAMPLE_INTERVAL_MS = 25; // To provide 40 updates per second.
- private static final double DEGREES_PER_US = (360.0 / 1024.0); // based on REV Through Bore Encoder
- private static final double VELOCITY_SAMPLES_PER_S = (1000.0 / VELOCITY_SAMPLE_INTERVAL_MS);
-
- // The correct drive and turn directions must be set for the Swerve Module based on the specific hardware geometry.
- // Forward motion must generate an increasing drive count.
- // Counter Clockwise steer rotation must generate an increasing Steer Angle (degrees)
- private static final boolean INVERT_DRIVE_ENCODER = false; // Set true if forward motion decreases drive "Count"
- private static final boolean INVERT_STEER_ENCODER = false; // Set true if counter clockwise steer action decreases steer "Degree"
-
- /***
- * @param octoquad provide access to configure OctoQuad
- * @param name name used for telemetry display
- * @param quadChannel Quadrature encoder channel. Pulse Width channel is this + 4
- * @param angleOffset Angle to subtract from absolute encoder to calibrate zero position. (see comments above)
- */
- public OctoSwerveModule (OctoQuad octoquad, String name, int quadChannel, double angleOffset) {
- this.name = name;
- this.channel = quadChannel;
- this.angleOffset = angleOffset;
- this.steerDirMult = INVERT_STEER_ENCODER ? -1 : 1 ; // create a multiplier to flip the steer angle.
-
- // Set the drive encoder direction. Note the absolute encoder does not have built-in direction inversion.
- octoquad.setSingleEncoderDirection(channel, INVERT_DRIVE_ENCODER ? OctoQuad.EncoderDirection.REVERSE : OctoQuad.EncoderDirection.FORWARD);
-
- // Set the velocity sample interval on both encoders
- octoquad.setSingleVelocitySampleInterval(channel, VELOCITY_SAMPLE_INTERVAL_MS);
- octoquad.setSingleVelocitySampleInterval(channel + 4, VELOCITY_SAMPLE_INTERVAL_MS);
-
- // Setup Absolute encoder pulse range to match REV Through Bore encoder.
- octoquad.setSingleChannelPulseWidthParams (channel + 4, new OctoQuad.ChannelPulseWidthParams(1,1024));
- }
-
- /***
- * Calculate the Swerve module's position and velocity values
- * @param encoderDataBlock most recent full data block read from OctoQuad.
- */
- public void updateModule(OctoQuad.EncoderDataBlock encoderDataBlock) {
- driveCounts = encoderDataBlock.positions[channel]; // get Counts.
- driveCountsPerSec = encoderDataBlock.velocities[channel] * VELOCITY_SAMPLES_PER_S; // convert counts/interval to counts/sec
-
- // convert uS to degrees. Add in any possible direction flip.
- steerDegrees = AngleUnit.normalizeDegrees((encoderDataBlock.positions[channel+ 4] * DEGREES_PER_US * steerDirMult) - angleOffset);
- // convert uS/interval to deg per sec. Add in any possible direction flip.
- steerDegreesPerSec = encoderDataBlock.velocities[channel + 4] * DEGREES_PER_US * steerDirMult * VELOCITY_SAMPLES_PER_S;
- }
-
- /**
- * Display the Swerve module's state as telemetry
- * @param telemetry OpMode Telemetry object
- */
- public void show(Telemetry telemetry) {
- telemetry.addData(name, "%8.0f %7.0f %7.0f %6.0f", driveCounts, driveCountsPerSec, steerDegrees, steerDegreesPerSec);
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorREV2mDistance.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorREV2mDistance.java
deleted file mode 100644
index 13883c34..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorREV2mDistance.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-Copyright (c) 2018 FIRST
-
-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.rev.Rev2mDistanceSensor;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.DistanceSensor;
-import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit;
-
-/*
- * This OpMode illustrates how to use the REV Robotics 2M Distance Sensor.
- *
- * The OpMode assumes that the sensor is configured with a name of "sensor_distance".
- *
- * 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
- *
- * See the sensor's product page: https://www.revrobotics.com/rev-31-1505/
- */
-@TeleOp(name = "Sensor: REV2mDistance", group = "Sensor")
-@Disabled
-public class SensorREV2mDistance extends LinearOpMode {
-
- private DistanceSensor sensorDistance;
-
- @Override
- public void runOpMode() {
- // you can use this as a regular DistanceSensor.
- sensorDistance = hardwareMap.get(DistanceSensor.class, "sensor_distance");
-
- // you can also cast this to a Rev2mDistanceSensor if you want to use added
- // methods associated with the Rev2mDistanceSensor class.
- Rev2mDistanceSensor sensorTimeOfFlight = (Rev2mDistanceSensor) sensorDistance;
-
- telemetry.addData(">>", "Press start to continue");
- telemetry.update();
-
- waitForStart();
- while(opModeIsActive()) {
- // generic DistanceSensor methods.
- telemetry.addData("deviceName", sensorDistance.getDeviceName() );
- telemetry.addData("range", String.format("%.01f mm", sensorDistance.getDistance(DistanceUnit.MM)));
- telemetry.addData("range", String.format("%.01f cm", sensorDistance.getDistance(DistanceUnit.CM)));
- telemetry.addData("range", String.format("%.01f m", sensorDistance.getDistance(DistanceUnit.METER)));
- telemetry.addData("range", String.format("%.01f in", sensorDistance.getDistance(DistanceUnit.INCH)));
-
- // Rev2mDistanceSensor specific methods.
- telemetry.addData("ID", String.format("%x", sensorTimeOfFlight.getModelID()));
- telemetry.addData("did time out", Boolean.toString(sensorTimeOfFlight.didTimeoutOccur()));
-
- telemetry.update();
- }
- }
-
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorSparkFunOTOS.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorSparkFunOTOS.java
deleted file mode 100644
index 3a25230f..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorSparkFunOTOS.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- SPDX-License-Identifier: MIT
-
- Copyright (c) 2024 SparkFun Electronics
-*/
-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 com.qualcomm.hardware.sparkfun.SparkFunOTOS;
-
-import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
-import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit;
-
-/*
- * This OpMode illustrates how to use the SparkFun Qwiic Optical Tracking Odometry Sensor (OTOS)
- *
- * The OpMode assumes that the sensor is configured with a name of "sensor_otos".
- *
- * 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
- *
- * See the sensor's product page: https://www.sparkfun.com/products/24904
- */
-@TeleOp(name = "Sensor: SparkFun OTOS", group = "Sensor")
-@Disabled
-public class SensorSparkFunOTOS extends LinearOpMode {
- // Create an instance of the sensor
- SparkFunOTOS myOtos;
-
- @Override
- public void runOpMode() throws InterruptedException {
- // Get a reference to the sensor
- myOtos = hardwareMap.get(SparkFunOTOS.class, "sensor_otos");
-
- // All the configuration for the OTOS is done in this helper method, check it out!
- configureOtos();
-
- // Wait for the start button to be pressed
- waitForStart();
-
- // Loop until the OpMode ends
- while (opModeIsActive()) {
- // Get the latest position, which includes the x and y coordinates, plus the
- // heading angle
- SparkFunOTOS.Pose2D pos = myOtos.getPosition();
-
- // Reset the tracking if the user requests it
- if (gamepad1.y) {
- myOtos.resetTracking();
- }
-
- // Re-calibrate the IMU if the user requests it
- if (gamepad1.x) {
- myOtos.calibrateImu();
- }
-
- // Inform user of available controls
- telemetry.addLine("Press Y (triangle) on Gamepad to reset tracking");
- telemetry.addLine("Press X (square) on Gamepad to calibrate the IMU");
- telemetry.addLine();
-
- // Log the position to the telemetry
- telemetry.addData("X coordinate", pos.x);
- telemetry.addData("Y coordinate", pos.y);
- telemetry.addData("Heading angle", pos.h);
-
- // Update the telemetry on the driver station
- telemetry.update();
- }
- }
-
- private void configureOtos() {
- telemetry.addLine("Configuring OTOS...");
- telemetry.update();
-
- // Set the desired units for linear and angular measurements. Can be either
- // meters or inches for linear, and radians or degrees for angular. If not
- // set, the default is inches and degrees. Note that this setting is not
- // persisted in the sensor, so you need to set at the start of all your
- // OpModes if using the non-default value.
- // myOtos.setLinearUnit(DistanceUnit.METER);
- myOtos.setLinearUnit(DistanceUnit.INCH);
- // myOtos.setAngularUnit(AnguleUnit.RADIANS);
- myOtos.setAngularUnit(AngleUnit.DEGREES);
-
- // Assuming you've mounted your sensor to a robot and it's not centered,
- // you can specify the offset for the sensor relative to the center of the
- // robot. The units default to inches and degrees, but if you want to use
- // different units, specify them before setting the offset! Note that as of
- // firmware version 1.0, these values will be lost after a power cycle, so
- // you will need to set them each time you power up the sensor. For example, if
- // the sensor is mounted 5 inches to the left (negative X) and 10 inches
- // forward (positive Y) of the center of the robot, and mounted 90 degrees
- // clockwise (negative rotation) from the robot's orientation, the offset
- // would be {-5, 10, -90}. These can be any value, even the angle can be
- // tweaked slightly to compensate for imperfect mounting (eg. 1.3 degrees).
- SparkFunOTOS.Pose2D offset = new SparkFunOTOS.Pose2D(0, 0, 0);
- myOtos.setOffset(offset);
-
- // Here we can set the linear and angular scalars, which can compensate for
- // scaling issues with the sensor measurements. Note that as of firmware
- // version 1.0, these values will be lost after a power cycle, so you will
- // need to set them each time you power up the sensor. They can be any value
- // from 0.872 to 1.127 in increments of 0.001 (0.1%). It is recommended to
- // first set both scalars to 1.0, then calibrate the angular scalar, then
- // the linear scalar. To calibrate the angular scalar, spin the robot by
- // multiple rotations (eg. 10) to get a precise error, then set the scalar
- // to the inverse of the error. Remember that the angle wraps from -180 to
- // 180 degrees, so for example, if after 10 rotations counterclockwise
- // (positive rotation), the sensor reports -15 degrees, the required scalar
- // would be 3600/3585 = 1.004. To calibrate the linear scalar, move the
- // robot a known distance and measure the error; do this multiple times at
- // multiple speeds to get an average, then set the linear scalar to the
- // inverse of the error. For example, if you move the robot 100 inches and
- // the sensor reports 103 inches, set the linear scalar to 100/103 = 0.971
- myOtos.setLinearScalar(1.0);
- myOtos.setAngularScalar(1.0);
-
- // The IMU on the OTOS includes a gyroscope and accelerometer, which could
- // have an offset. Note that as of firmware version 1.0, the calibration
- // will be lost after a power cycle; the OTOS performs a quick calibration
- // when it powers up, but it is recommended to perform a more thorough
- // calibration at the start of all your OpModes. Note that the sensor must
- // be completely stationary and flat during calibration! When calling
- // calibrateImu(), you can specify the number of samples to take and whether
- // to wait until the calibration is complete. If no parameters are provided,
- // it will take 255 samples and wait until done; each sample takes about
- // 2.4ms, so about 612ms total
- myOtos.calibrateImu();
-
- // Reset the tracking algorithm - this resets the position to the origin,
- // but can also be used to recover from some rare tracking errors
- myOtos.resetTracking();
-
- // After resetting the tracking, the OTOS will report that the robot is at
- // the origin. If your robot does not start at the origin, or you have
- // another source of location information (eg. vision odometry), you can set
- // the OTOS location to match and it will continue to track from there.
- SparkFunOTOS.Pose2D currentPosition = new SparkFunOTOS.Pose2D(0, 0, 0);
- myOtos.setPosition(currentPosition);
-
- // Get the hardware and firmware version
- SparkFunOTOS.Version hwVersion = new SparkFunOTOS.Version();
- SparkFunOTOS.Version fwVersion = new SparkFunOTOS.Version();
- myOtos.getVersionInfo(hwVersion, fwVersion);
-
- telemetry.addLine("OTOS configured! Press start to get position data!");
- telemetry.addLine();
- telemetry.addLine(String.format("OTOS Hardware Version: v%d.%d", hwVersion.major, hwVersion.minor));
- telemetry.addLine(String.format("OTOS Firmware Version: v%d.%d", fwVersion.major, fwVersion.minor));
- telemetry.update();
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorTouch.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorTouch.java
deleted file mode 100644
index 3d794472..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorTouch.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Copyright (c) 2017 FIRST. 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 com.qualcomm.robotcore.hardware.TouchSensor;
-
-/*
- * This OpMode demonstrates how to use a REV Robotics Touch Sensor, REV Robotics Magnetic Limit Switch, or other device
- * that implements the TouchSensor interface. Any touch sensor that connects its output to ground when pressed
- * (known as "active low") can be configured as a "REV Touch Sensor". This includes REV's Magnetic Limit Switch.
- *
- * The OpMode assumes that the touch sensor is configured with a name of "sensor_touch".
- *
- * A REV Robotics Touch Sensor must be configured on digital port number 1, 3, 5, or 7.
- * A Magnetic Limit Switch can be configured on any digital port.
- *
- * 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 = "Sensor: REV touch sensor", group = "Sensor")
-@Disabled
-public class SensorTouch extends LinearOpMode {
- TouchSensor touchSensor; // Touch sensor Object
-
- @Override
- public void runOpMode() {
-
- // get a reference to our touchSensor object.
- touchSensor = hardwareMap.get(TouchSensor.class, "sensor_touch");
-
- // wait for the start button to be pressed.
- waitForStart();
-
- // while the OpMode is active, loop and read whether the sensor is being pressed.
- // Note we use opModeIsActive() as our loop condition because it is an interruptible method.
- while (opModeIsActive()) {
-
- // send the info back to driver station using telemetry function.
- if (touchSensor.isPressed()) {
- telemetry.addData("Touch Sensor", "Is Pressed");
- } else {
- telemetry.addData("Touch Sensor", "Is Not Pressed");
- }
-
- telemetry.update();
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/UtilityCameraFrameCapture.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/UtilityCameraFrameCapture.java
deleted file mode 100644
index 69420cca..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/UtilityCameraFrameCapture.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2023 FIRST
- *
- * 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 android.util.Size;
-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.vision.VisionPortal;
-
-import java.util.Locale;
-
-/*
- * This OpMode helps calibrate a webcam or RC phone camera, useful for AprilTag pose estimation
- * with the FTC VisionPortal. It captures a camera frame (image) and stores it on the Robot Controller
- * (Control Hub or RC phone), with each press of the gamepad button X (or Square).
- * Full calibration instructions are here:
- *
- * https://ftc-docs.firstinspires.org/camera-calibration
- *
- * In Android Studio, copy this class into your "teamcode" folder with a new name.
- * Remove or comment out the @Disabled line to add this OpMode to the Driver Station OpMode list.
- *
- * In OnBot Java, use "Add File" to add this OpMode from the list of Samples.
- */
-
-@TeleOp(name = "Utility: Camera Frame Capture", group = "Utility")
-@Disabled
-public class UtilityCameraFrameCapture extends LinearOpMode
-{
- /*
- * EDIT THESE PARAMETERS AS NEEDED
- */
- final boolean USING_WEBCAM = false;
- final BuiltinCameraDirection INTERNAL_CAM_DIR = BuiltinCameraDirection.BACK;
- final int RESOLUTION_WIDTH = 640;
- final int RESOLUTION_HEIGHT = 480;
-
- // Internal state
- boolean lastX;
- int frameCount;
- long capReqTime;
-
- @Override
- public void runOpMode()
- {
- VisionPortal portal;
-
- if (USING_WEBCAM)
- {
- portal = new VisionPortal.Builder()
- .setCamera(hardwareMap.get(WebcamName.class, "Webcam 1"))
- .setCameraResolution(new Size(RESOLUTION_WIDTH, RESOLUTION_HEIGHT))
- .build();
- }
- else
- {
- portal = new VisionPortal.Builder()
- .setCamera(INTERNAL_CAM_DIR)
- .setCameraResolution(new Size(RESOLUTION_WIDTH, RESOLUTION_HEIGHT))
- .build();
- }
-
- while (!isStopRequested())
- {
- boolean x = gamepad1.x;
-
- if (x && !lastX)
- {
- portal.saveNextFrameRaw(String.format(Locale.US, "CameraFrameCapture-%06d", frameCount++));
- capReqTime = System.currentTimeMillis();
- }
-
- lastX = x;
-
- telemetry.addLine("######## Camera Capture Utility ########");
- telemetry.addLine(String.format(Locale.US, " > Resolution: %dx%d", RESOLUTION_WIDTH, RESOLUTION_HEIGHT));
- telemetry.addLine(" > Press X (or Square) to capture a frame");
- telemetry.addData(" > Camera Status", portal.getCameraState());
-
- if (capReqTime != 0)
- {
- telemetry.addLine("\nCaptured Frame!");
- }
-
- if (capReqTime != 0 && System.currentTimeMillis() - capReqTime > 1000)
- {
- capReqTime = 0;
- }
-
- telemetry.update();
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/UtilityOctoQuadConfigMenu.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/UtilityOctoQuadConfigMenu.java
deleted file mode 100644
index a962919f..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/UtilityOctoQuadConfigMenu.java
+++ /dev/null
@@ -1,812 +0,0 @@
-/*
- * Copyright (c) 2024 DigitalChickenLabs
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.firstinspires.ftc.robotcontroller.external.samples;
-
-import com.qualcomm.hardware.digitalchickenlabs.OctoQuad;
-import com.qualcomm.robotcore.eventloop.opmode.Disabled;
-import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
-import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
-import com.qualcomm.robotcore.hardware.Gamepad;
-
-import org.firstinspires.ftc.robotcore.external.Telemetry;
-
-import java.util.ArrayList;
-import java.util.Stack;
-
-/*
- * This OpMode illustrates how to use the DigitalChickenLabs OctoQuad Quadrature Encoder & Pulse Width Interface Module.
- *
- * The OctoQuad has 8 input channels that can used to read either Relative Quadrature Encoders or Pulse-Width Absolute Encoder inputs.
- * Relative Quadrature encoders are found on most FTC motors, and some stand-alone position sensors like the REV Thru-Bore encoder.
- * Pulse-Width encoders are less common. The REV Thru-Bore encoder can provide its absolute position via a variable pulse width,
- * as can several sonar rangefinders such as the MaxBotix MB1000 series.
- *
- * This OpMode assumes that the OctoQuad is attached to an I2C interface named "octoquad" in the robot configuration.
- *
- * Remove or comment out the @Disabled line to add this OpMode to the Driver Station OpMode list
- *
- * Select, Init and run the "OctoQuad Configuration Tool" OpMode
- * Read the blue User-Interface tips at the top of the telemetry screen.
- * Use the UI buttons to navigate the menu and make any desired changes to the OctoQuad configuration.
- * Use the Program Settings To FLASH option to make any changes permanent.
- *
- * See the sensor's product page: https://www.tindie.com/products/digitalchickenlabs/octoquad-8ch-quadrature-pulse-width-decoder/
- */
-@TeleOp(name = "OctoQuad Configuration Tool", group="OctoQuad")
-@Disabled
-public class UtilityOctoQuadConfigMenu extends LinearOpMode
-{
- TelemetryMenu.MenuElement rootMenu = new TelemetryMenu.MenuElement("OctoQuad Config Menu", true);
- TelemetryMenu.MenuElement menuHwInfo = new TelemetryMenu.MenuElement("Hardware Information", false);
- TelemetryMenu.EnumOption optionI2cResetMode;
- TelemetryMenu.EnumOption optionChannelBankConfig;
-
- TelemetryMenu.MenuElement menuEncoderDirections = new TelemetryMenu.MenuElement("Set Encoder Directions", false);
- TelemetryMenu.BooleanOption[] optionsEncoderDirections = new TelemetryMenu.BooleanOption[OctoQuad.NUM_ENCODERS];
-
- TelemetryMenu.MenuElement menuVelocityIntervals = new TelemetryMenu.MenuElement("Velocity Measurement Intervals", false);
- TelemetryMenu.IntegerOption[] optionsVelocityIntervals = new TelemetryMenu.IntegerOption[OctoQuad.NUM_ENCODERS];
-
- TelemetryMenu.MenuElement menuAbsParams = new TelemetryMenu.MenuElement("Abs. Encoder Pulse Width Params", false);
- TelemetryMenu.IntegerOption[] optionsAbsParamsMax = new TelemetryMenu.IntegerOption[OctoQuad.NUM_ENCODERS];
- TelemetryMenu.IntegerOption[] optionsAbsParamsMin = new TelemetryMenu.IntegerOption[OctoQuad.NUM_ENCODERS];
-
- TelemetryMenu.OptionElement optionProgramToFlash;
- TelemetryMenu.OptionElement optionSendToRAM;
-
- TelemetryMenu.StaticClickableOption optionExit;
-
- OctoQuad octoquad;
-
- boolean error = false;
-
- @Override
- public void runOpMode()
- {
- octoquad = hardwareMap.getAll(OctoQuad.class).get(0);
-
- if(octoquad.getChipId() != OctoQuad.OCTOQUAD_CHIP_ID)
- {
- telemetry.addLine("Error: cannot communicate with OctoQuad. Check your wiring and configuration and try again");
- telemetry.update();
-
- error = true;
- }
- else
- {
- if(octoquad.getFirmwareVersion().maj != OctoQuad.SUPPORTED_FW_VERSION_MAJ)
- {
- telemetry.addLine("Error: The OctoQuad is running a different major firmware version than this driver was built for. Cannot run configuration tool");
- telemetry.update();
-
- error = true;
- }
- }
-
- if(error)
- {
- waitForStart();
- return;
- }
-
- telemetry.addLine("Retrieving current configuration from OctoQuad");
- telemetry.update();
-
- optionExit = new TelemetryMenu.StaticClickableOption("Exit configuration menu")
- {
- @Override
- void onClick() // called on OpMode thread
- {
- requestOpModeStop();
- }
- };
-
- optionI2cResetMode = new TelemetryMenu.EnumOption("I2C Reset Mode", OctoQuad.I2cRecoveryMode.values(), octoquad.getI2cRecoveryMode());
- optionChannelBankConfig = new TelemetryMenu.EnumOption("Channel Bank Modes", OctoQuad.ChannelBankConfig.values(), octoquad.getChannelBankConfig());
-
- menuHwInfo.addChild(new TelemetryMenu.StaticItem("Board Firmware: v" + octoquad.getFirmwareVersion()));
- //menuHwInfo.addChild(new TelemetryMenu.StaticItem("Board unique ID: FIXME"));
-
- for(int i = 0; i < OctoQuad.NUM_ENCODERS; i++)
- {
- optionsEncoderDirections[i] = new TelemetryMenu.BooleanOption(
- String.format("Encoder %d direction", i),
- octoquad.getSingleEncoderDirection(i) == OctoQuad.EncoderDirection.REVERSE,
- "-",
- "+");
- }
- menuEncoderDirections.addChildren(optionsEncoderDirections);
-
- for(int i = 0; i < OctoQuad.NUM_ENCODERS; i++)
- {
- optionsVelocityIntervals[i] = new TelemetryMenu.IntegerOption(
- String.format("Chan %d velocity intvl", i),
- OctoQuad.MIN_VELOCITY_MEASUREMENT_INTERVAL_MS,
- OctoQuad.MAX_VELOCITY_MEASUREMENT_INTERVAL_MS,
- octoquad.getSingleVelocitySampleInterval(i));
- }
- menuVelocityIntervals.addChildren(optionsVelocityIntervals);
-
- for(int i = 0; i < OctoQuad.NUM_ENCODERS; i++)
- {
- OctoQuad.ChannelPulseWidthParams params = octoquad.getSingleChannelPulseWidthParams(i);
-
- optionsAbsParamsMax[i] = new TelemetryMenu.IntegerOption(
- String.format("Chan %d max pulse length", i),
- OctoQuad.MIN_PULSE_WIDTH_US,
- OctoQuad.MAX_PULSE_WIDTH_US,
- params.max_length_us);
-
- optionsAbsParamsMin[i] = new TelemetryMenu.IntegerOption(
- String.format("Chan %d min pulse length", i),
- OctoQuad.MIN_PULSE_WIDTH_US,
- OctoQuad.MAX_PULSE_WIDTH_US,
- params.min_length_us);
- }
- menuAbsParams.addChildren(optionsAbsParamsMin);
- menuAbsParams.addChildren(optionsAbsParamsMax);
-
- optionProgramToFlash = new TelemetryMenu.OptionElement()
- {
- String name = "Program Settings to FLASH";
- long lastClickTime = 0;
-
- @Override
- protected String getDisplayText()
- {
- if(lastClickTime == 0)
- {
- return name;
- }
- else
- {
- if(System.currentTimeMillis() - lastClickTime < 1000)
- {
- return name + " **OK**";
- }
- else
- {
- lastClickTime = 0;
- return name;
- }
- }
- }
-
- @Override
- void onClick()
- {
- sendSettingsToRam();
- octoquad.saveParametersToFlash();
- lastClickTime = System.currentTimeMillis();
- }
- };
-
- optionSendToRAM = new TelemetryMenu.OptionElement()
- {
- String name = "Send Settings to RAM";
- long lastClickTime = 0;
-
- @Override
- protected String getDisplayText()
- {
- if(lastClickTime == 0)
- {
- return name;
- }
- else
- {
- if(System.currentTimeMillis() - lastClickTime < 1000)
- {
- return name + " **OK**";
- }
- else
- {
- lastClickTime = 0;
- return name;
- }
- }
- }
-
- @Override
- void onClick()
- {
- sendSettingsToRam();
- lastClickTime = System.currentTimeMillis();
- }
- };
-
- rootMenu.addChild(menuHwInfo);
- rootMenu.addChild(optionI2cResetMode);
- rootMenu.addChild(optionChannelBankConfig);
- rootMenu.addChild(menuEncoderDirections);
- rootMenu.addChild(menuVelocityIntervals);
- rootMenu.addChild(menuAbsParams);
- rootMenu.addChild(optionProgramToFlash);
- rootMenu.addChild(optionSendToRAM);
- rootMenu.addChild(optionExit);
-
- TelemetryMenu menu = new TelemetryMenu(telemetry, rootMenu);
-
- while (!isStopRequested())
- {
- menu.loop(gamepad1);
- telemetry.update();
- sleep(20);
- }
- }
-
- void sendSettingsToRam()
- {
- for(int i = 0; i < OctoQuad.NUM_ENCODERS; i++)
- {
- octoquad.setSingleEncoderDirection(i, optionsEncoderDirections[i].getValue() ? OctoQuad.EncoderDirection.REVERSE : OctoQuad.EncoderDirection.FORWARD);
- octoquad.setSingleVelocitySampleInterval(i, optionsVelocityIntervals[i].getValue());
-
- OctoQuad.ChannelPulseWidthParams params = new OctoQuad.ChannelPulseWidthParams();
- params.max_length_us = optionsAbsParamsMax[i].getValue();
- params.min_length_us = optionsAbsParamsMin[i].getValue();
-
- octoquad.setSingleChannelPulseWidthParams(i, params);
- }
-
- octoquad.setI2cRecoveryMode((OctoQuad.I2cRecoveryMode) optionI2cResetMode.getValue());
- octoquad.setChannelBankConfig((OctoQuad.ChannelBankConfig) optionChannelBankConfig.getValue());
- }
-
- /*
- * Copyright (c) 2023 OpenFTC Team
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
- public static class TelemetryMenu
- {
- private final MenuElement root;
- private MenuElement currentLevel;
-
- private boolean dpadUpPrev;
- private boolean dpadDnPrev;
- private boolean dpadRightPrev;
- private boolean dpadLeftPrev;
- private boolean xPrev;
- private boolean lbPrev;
-
- private int selectedIdx = 0;
- private Stack selectedIdxStack = new Stack<>();
-
- private final Telemetry telemetry;
-
- /**
- * TelemetryMenu constructor
- * @param telemetry pass in 'telemetry' from your OpMode
- * @param root the root menu element
- */
- public TelemetryMenu(Telemetry telemetry, MenuElement root)
- {
- this.root = root;
- this.currentLevel = root;
- this.telemetry = telemetry;
-
- telemetry.setDisplayFormat(Telemetry.DisplayFormat.HTML);
- telemetry.setMsTransmissionInterval(50);
- }
-
- /**
- * Call this from inside your loop to put the current menu state into
- * telemetry, and process gamepad inputs for navigating the menu
- * @param gamepad the gamepad you want to use to navigate the menu
- */
- public void loop(Gamepad gamepad)
- {
- // Capture current state of the gamepad buttons we care about;
- // We can only look once or we risk a race condition
- boolean dpadUp = gamepad.dpad_up;
- boolean dpadDn = gamepad.dpad_down;
- boolean dpadRight = gamepad.dpad_right;
- boolean dpadLeft = gamepad.dpad_left;
- boolean x = gamepad.x;
- boolean lb = gamepad.left_bumper;
-
- // Figure out who our children our at this level
- // and figure out which item is currently highlighted
- // with the selection pointer
- ArrayList children = currentLevel.children();
- Element currentSelection = children.get(selectedIdx);
-
- // Left and right are inputs to the selected item (if it's an Option)
- if (currentSelection instanceof OptionElement)
- {
- if (dpadRight && !dpadRightPrev) // rising edge
- {
- ((OptionElement) currentSelection).onRightInput();
- }
- else if (dpadLeft && !dpadLeftPrev) // rising edge
- {
- ((OptionElement) currentSelection).onLeftInput();
- }
- }
-
- // Up and down navigate the current selection pointer
- if (dpadUp && !dpadUpPrev) // rising edge
- {
- selectedIdx--; // Move selection pointer up
- }
- else if (dpadDn && !dpadDnPrev) // rising edge
- {
- selectedIdx++; // Move selection pointer down
- }
-
- // Make selected index sane (don't let it go out of bounds) :eyes:
- if (selectedIdx >= children.size())
- {
- selectedIdx = children.size()-1;
- }
- else if (selectedIdx < 0)
- {
- selectedIdx = 0;
- }
-
- // Select: either enter submenu or input to option
- else if (x && !xPrev) // rising edge
- {
- // Select up element
- if (currentSelection instanceof SpecialUpElement)
- {
- // We can only go up if we're not at the root level
- if (currentLevel != root)
- {
- // Restore selection pointer to where it was before
- selectedIdx = selectedIdxStack.pop();
-
- // Change to the parent level
- currentLevel = currentLevel.parent();
- }
- }
- // Input to option
- else if (currentSelection instanceof OptionElement)
- {
- ((OptionElement) currentSelection).onClick();
- }
- // Enter submenu
- else if (currentSelection instanceof MenuElement)
- {
- // Save our current selection pointer so we can restore it
- // later if the user navigates back up a level
- selectedIdxStack.push(selectedIdx);
-
- // We have no idea what's in the submenu :monkey: so best to
- // just set the selection pointer to the first element
- selectedIdx = 0;
-
- // Now the current level becomes the submenu that the selection
- // pointer was on
- currentLevel = (MenuElement) currentSelection;
- }
- }
-
- // Go up a level
- else if (lb && !lbPrev)
- {
- // We can only go up if we're not at the root level
- if (currentLevel != root)
- {
- // Restore selection pointer to where it was before
- selectedIdx = selectedIdxStack.pop();
-
- // Change to the parent level
- currentLevel = currentLevel.parent();
- }
- }
-
- // Save the current button states so that we can look for
- // the rising edge the next time around the loop :)
- dpadUpPrev = dpadUp;
- dpadDnPrev = dpadDn;
- dpadRightPrev = dpadRight;
- dpadLeftPrev = dpadLeft;
- xPrev = x;
- lbPrev = lb;
-
- // Start building the text display.
- // First, we add the static directions for gamepad operation
- StringBuilder builder = new StringBuilder();
- builder.append("");
- builder.append("Navigate items.....dpad up/down\n")
- .append("Select.............X or Square\n")
- .append("Edit option........dpad left/right\n")
- .append("Up one level.......left bumper\n");
- builder.append("");
- builder.append("\n");
-
- // Now actually add the menu options. We start by adding the name of the current menu level.
- builder.append("");
- builder.append("Current Menu: ").append(currentLevel.name).append("\n");
-
- // Now we loop through all the child elements of this level and add them
- for (int i = 0; i < children.size(); i++)
- {
- // If the selection pointer is at this index, put a green dot in the box :)
- if (selectedIdx == i)
- {
- builder.append("[•] ");
- }
- // Otherwise, just put an empty box
- else
- {
- builder.append("[ ] ");
- }
-
- // Figure out who the selection pointer is pointing at :eyes:
- Element e = children.get(i);
-
- // If it's pointing at a submenu, indicate that it's a submenu to the user
- // by prefixing "> " to the name.
- if (e instanceof MenuElement)
- {
- builder.append("> ");
- }
-
- // Finally, add the element's name
- builder.append(e.getDisplayText());
-
- // We musn't forget the newline
- builder.append("\n");
- }
-
- // Don't forget to close the font tag either
- builder.append("");
-
- // Build the string!!!! :nerd:
- String menu = builder.toString();
-
- // Add it to telemetry
- telemetry.addLine(menu);
- }
-
- public static class MenuElement extends Element
- {
- private String name;
- private ArrayList children = new ArrayList<>();
-
- /**
- * Create a new MenuElement; may either be the root menu, or a submenu (set isRoot accordingly)
- * @param name the name for this menu
- * @param isRoot whether this is a root menu, or a submenu
- */
- public MenuElement(String name, boolean isRoot)
- {
- this.name = name;
-
- // If it's not the root menu, we add the up one level option as the first element
- if (!isRoot)
- {
- children.add(new SpecialUpElement());
- }
- }
-
- /**
- * Add a child element to this menu (may either be an Option or another menu)
- * @param child the child element to add
- */
- public void addChild(Element child)
- {
- child.setParent(this);
- children.add(child);
- }
-
- /**
- * Add multiple child elements to this menu (may either be option, or another menu)
- * @param children the children to add
- */
- public void addChildren(Element[] children)
- {
- for (Element e : children)
- {
- e.setParent(this);
- this.children.add(e);
- }
- }
-
- @Override
- protected String getDisplayText()
- {
- return name;
- }
-
- private ArrayList children()
- {
- return children;
- }
- }
-
- public static abstract class OptionElement extends Element
- {
- /**
- * Override this to get notified when the element is clicked
- */
- void onClick() {}
-
- /**
- * Override this to get notified when the element gets a "left edit" input
- */
- protected void onLeftInput() {}
-
- /**
- * Override this to get notified when the element gets a "right edit" input
- */
- protected void onRightInput() {}
- }
-
- public static class EnumOption extends OptionElement
- {
- protected int idx = 0;
- protected Enum[] e;
- protected String name;
-
- public EnumOption(String name, Enum[] e)
- {
- this.e = e;
- this.name = name;
- }
-
- public EnumOption(String name, Enum[] e, Enum def)
- {
- this(name, e);
- idx = def.ordinal();
- }
-
- @Override
- public void onLeftInput()
- {
- idx++;
-
- if(idx > e.length-1)
- {
- idx = 0;
- }
- }
-
- @Override
- public void onRightInput()
- {
- idx--;
-
- if(idx < 0)
- {
- idx = e.length-1;
- }
- }
-
- @Override
- public void onClick()
- {
- //onRightInput();
- }
-
- @Override
- protected String getDisplayText()
- {
- return String.format("%s: %s", name, e[idx].name());
- }
-
- public Enum getValue()
- {
- return e[idx];
- }
- }
-
- public static class IntegerOption extends OptionElement
- {
- protected int i;
- protected int min;
- protected int max;
- protected String name;
-
- public IntegerOption(String name, int min, int max, int def)
- {
- this.name = name;
- this.min = min;
- this.max = max;
- this.i = def;
- }
-
- @Override
- public void onLeftInput()
- {
- i--;
-
- if(i < min)
- {
- i = max;
- }
- }
-
- @Override
- public void onRightInput()
- {
- i++;
-
- if(i > max)
- {
- i = min;
- }
- }
-
- @Override
- public void onClick()
- {
- //onRightInput();
- }
-
- @Override
- protected String getDisplayText()
- {
- return String.format("%s: %d", name, i);
- }
-
- public int getValue()
- {
- return i;
- }
- }
-
- static class BooleanOption extends OptionElement
- {
- private String name;
- private boolean val = true;
-
- private String customTrue;
- private String customFalse;
-
- BooleanOption(String name, boolean def)
- {
- this.name = name;
- this.val = def;
- }
-
- BooleanOption(String name, boolean def, String customTrue, String customFalse)
- {
- this(name, def);
- this.customTrue = customTrue;
- this.customFalse = customFalse;
- }
-
- @Override
- public void onLeftInput()
- {
- val = !val;
- }
-
- @Override
- public void onRightInput()
- {
- val = !val;
- }
-
- @Override
- public void onClick()
- {
- val = !val;
- }
-
- @Override
- protected String getDisplayText()
- {
- String valStr;
-
- if(customTrue != null && customFalse != null)
- {
- valStr = val ? customTrue : customFalse;
- }
- else
- {
- valStr = val ? "true" : "false";
- }
-
- return String.format("%s: %s", name, valStr);
- }
-
- public boolean getValue()
- {
- return val;
- }
- }
-
- /**
- *
- */
- public static class StaticItem extends OptionElement
- {
- private String name;
-
- public StaticItem(String name)
- {
- this.name = name;
- }
-
- @Override
- protected String getDisplayText()
- {
- return name;
- }
- }
-
- public static abstract class StaticClickableOption extends OptionElement
- {
- private String name;
-
- public StaticClickableOption(String name)
- {
- this.name = name;
- }
-
- abstract void onClick();
-
- @Override
- protected String getDisplayText()
- {
- return name;
- }
- }
-
- private static abstract class Element
- {
- private MenuElement parent;
-
- protected void setParent(MenuElement parent)
- {
- this.parent = parent;
- }
-
- protected MenuElement parent()
- {
- return parent;
- }
-
- protected abstract String getDisplayText();
- }
-
- private static class SpecialUpElement extends Element
- {
- @Override
- protected String getDisplayText()
- {
- return ".. ↰ Up One Level";
- }
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/readme.md b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/readme.md
deleted file mode 100644
index 326978de..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/readme.md
+++ /dev/null
@@ -1,45 +0,0 @@
-
-## Caution
-No Team-specific code should be placed or modified in this ``.../samples`` folder.
-
-Samples should be Copied from here, and then Pasted into the team's
-[/TeamCode/src/main/java/org/firstinspires/ftc/teamcode](../../../../../../../../../../TeamCode/src/main/java/org/firstinspires/ftc/teamcode)
- folder, using the Android Studio cut and paste commands. This automatically changes all file and
-class names to be consistent. From there, the sample can be modified to suit the team's needs.
-
-For more detailed instructions see the /teamcode readme.
-
-### Naming of Samples
-
-To gain a better understanding of how the samples are organized, and how to interpret the
-naming system, it will help to understand the conventions that were used during their creation.
-
-These conventions are described (in detail) in the sample_conventions.md file in this folder.
-
-To summarize: A range of different samples classes will reside in the java/external/samples.
-The class names will follow a naming convention which indicates the purpose of each class.
-The prefix of the name will be one of the following:
-
-Basic: This is a minimally functional OpMode used to illustrate the skeleton/structure
- of a particular style of OpMode. These are bare bones examples.
-
-Sensor: This is a Sample OpMode that shows how to use a specific sensor.
- It is not intended to drive a functioning robot, it is simply showing the minimal code
- required to read and display the sensor values.
-
-Robot: This is a Sample OpMode that assumes a simple two-motor (differential) drive base.
- It may be used to provide a common baseline driving OpMode, or
- to demonstrate how a particular sensor or concept can be used to navigate.
-
-Concept: This is a sample OpMode that illustrates performing a specific function or concept.
- These may be complex, but their operation should be explained clearly in the comments,
- or the comments should reference an external doc, guide or tutorial.
- Each OpMode should try to only demonstrate a single concept so they are easy to
- locate based on their name. These OpModes may not produce a drivable robot.
-
-After the prefix, other conventions will apply:
-
-* Sensor class names are constructed as: Sensor - Company - Type
-* Robot class names are constructed as: Robot - Mode - Action - OpModetype
-* Concept class names are constructed as: Concept - Topic - OpModetype
-
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/sample_conventions.md b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/sample_conventions.md
deleted file mode 100644
index e85e6254..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/sample_conventions.md
+++ /dev/null
@@ -1,113 +0,0 @@
-## Sample Class/Opmode conventions
-#### V 1.1.0 8/9/2017
-
-This document defines the FTC Sample OpMode and Class conventions.
-
-### OpMode Name
-
-To gain a better understanding of how the samples are organized, and how to interpret the
-naming system, it will help to understand the conventions that were used during their creation.
-
-To summarize: A range of different samples classes will reside in the java/external/samples.
-The class names will follow a naming convention which indicates the purpose of each class.
-The prefix of the name will be one of the following:
-
-Basic: This is a minimally functional OpMode used to illustrate the skeleton/structure
- of a particular style of OpMode. These are bare bones examples.
-
-Sensor: This is a Sample OpMode that shows how to use a specific sensor.
- It is not intended to drive a functioning robot, it is simply showing the minimal code
- required to read and display the sensor values.
-
-Robot: This is a Sample OpMode that assumes a simple two-motor (differential) drive base.
- It may be used to provide a common baseline driving OpMode, or
- to demonstrate how a particular sensor or concept can be used to navigate.
-
-Concept: This is a sample OpMode that illustrates performing a specific function or concept.
- These may be complex, but their operation should be explained clearly in the comments,
- or the comments should reference an external doc, guide or tutorial.
- Each OpMode should try to only demonstrate a single concept so they are easy to
- locate based on their name. These OpModes may not produce a drivable robot.
-
-Utility: This sample type is provided as a useful tool, or aide, to perform some specific development task.
- It is not expected to be something you would include in your own robot code.
- To use the tool, comment out the @Disabled annotation and build the App.
- Read the comments found in the sample for an explanation of its intended use.
-
-After the prefix, other conventions will apply:
-
-* Sensor class names should constructed as: Sensor - Company - Type
-* Robot class names should be constructed as: Robot - Mode - Action - OpModetype
-* Concept class names should be constructed as: Concept - Topic - OpModetype
-
-### Sample OpMode Content/Style
-
-Code is formatted as per the Google Style Guide:
-
-https://google.github.io/styleguide/javaguide.html
-
-With “Sensor” and “Hardware” samples, the code should demonstrate the essential function,
-and not be embellished with too much additional “clever” code. If a sensor has special
-addressing needs, or has a variety of modes or outputs, these should be demonstrated as
-simply as possible.
-
-Special programming methods, or robot control techniques should be reserved for “Concept” Samples,
-and where possible, Samples should strive to only demonstrate a single concept,
-eg: State machine coding, or a User Menu system, and not combine them into a single “all inclusive”
-sample. This will prevent an “all inclusive” Sample being deleted just because one part of it
-becomes obsolete.
-
-### Device Configuration Names
-
-The following device names are used in the external samples
-
-** Motors:
-left_drive
-right_drive
-left_arm
-
-** Servos:
-left_hand
-right_hand
-arm
-claw
-
-** Sensors:
-sensor_color
-sensor_ir
-sensor_light
-sensor_ods
-sensor_range
-sensor_touch
-sensor_color_distance
-sensor_digital
-digin
-digout
-
-** Localization:
-compass
-gyro
-imu
-navx
-
-### Device Object Names
-
-Device Object names should use the same words as the device’s configuration name, but they
-should be re-structured to be a suitable Java variable name. This should keep the same word order,
-but adopt the style of beginning with a lower case letter, and then each subsequent word
-starting with an upper case letter.
-
-Eg: from the examples above: tool, leftMotor, rightClawServo, rearLightSensor.
-
-Note: Sometimes it’s helpful to put the device type first, followed by the variant.
-eg: motorLeft and motorRight, but this should only be done if the same word order
-is used on the device configuration name.
-
-### OpMode code Comments
-
-Sample comments should read like normal code comments, that is, as an explanation of what the
-sample code is doing. They should NOT be directives to the user,
-like: “insert your joystick code here” as these comments typically aren’t
-detailed enough to be useful. They also often get left in the code and become garbage.
-
-Instead, an example of the joystick code should be shown with a comment describing what it is doing.
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/FtcOpModeRegister.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/FtcOpModeRegister.java
deleted file mode 100644
index ceab67db..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/FtcOpModeRegister.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright (c) 2014, 2015 Qualcomm Technologies Inc
-
-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 Qualcomm Technologies Inc 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.internal;
-
-import com.qualcomm.robotcore.eventloop.opmode.OpModeManager;
-import com.qualcomm.robotcore.eventloop.opmode.OpModeRegister;
-
-/**
- * {@link FtcOpModeRegister} is responsible for registering OpModes for use in an FTC game.
- * @see #register(OpModeManager)
- */
-public class FtcOpModeRegister implements OpModeRegister {
-
- /**
- * {@link #register(OpModeManager)} is called by the SDK game in order to register
- * OpMode classes or instances that will participate in an FTC game.
- *
- * There are two mechanisms by which an OpMode may be registered.
- *
- * 1) The preferred method is by means of class annotations in the OpMode itself.
- * See, for example the class annotations in {@link org.firstinspires.ftc.robotcontroller.external.samples.ConceptNullOp}.
- *
- * 2) The other, retired, method is to modify this {@link #register(OpModeManager)}
- * method to include explicit calls to OpModeManager.register().
- * This method of modifying this file directly is discouraged, as it
- * makes updates to the SDK harder to integrate into your code.
- *
- * @param manager the object which contains methods for carrying out OpMode registrations
- *
- * @see com.qualcomm.robotcore.eventloop.opmode.TeleOp
- * @see com.qualcomm.robotcore.eventloop.opmode.Autonomous
- */
- public void register(OpModeManager manager) {
-
- /**
- * Any manual OpMode class registrations should go here.
- */
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/FtcRobotControllerActivity.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/FtcRobotControllerActivity.java
deleted file mode 100644
index 3f1f77ce..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/FtcRobotControllerActivity.java
+++ /dev/null
@@ -1,845 +0,0 @@
-/* Copyright (c) 2014, 2015 Qualcomm Technologies Inc
-
-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 Qualcomm Technologies Inc 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.internal;
-
-import android.app.ActionBar;
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.SharedPreferences;
-import android.content.res.Configuration;
-import android.hardware.usb.UsbDevice;
-import android.hardware.usb.UsbManager;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.preference.PreferenceManager;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.WindowManager;
-import android.webkit.WebView;
-import android.widget.ImageButton;
-import android.widget.LinearLayout;
-import android.widget.LinearLayout.LayoutParams;
-import android.widget.PopupMenu;
-import android.widget.TextView;
-
-import com.google.blocks.ftcrobotcontroller.ProgrammingWebHandlers;
-import com.google.blocks.ftcrobotcontroller.runtime.BlocksOpMode;
-import com.qualcomm.ftccommon.ClassManagerFactory;
-import com.qualcomm.ftccommon.FtcAboutActivity;
-import com.qualcomm.ftccommon.FtcEventLoop;
-import com.qualcomm.ftccommon.FtcEventLoopIdle;
-import com.qualcomm.ftccommon.FtcRobotControllerService;
-import com.qualcomm.ftccommon.FtcRobotControllerService.FtcRobotControllerBinder;
-import com.qualcomm.ftccommon.FtcRobotControllerSettingsActivity;
-import com.qualcomm.ftccommon.LaunchActivityConstantsList;
-import com.qualcomm.ftccommon.LaunchActivityConstantsList.RequestCode;
-import com.qualcomm.ftccommon.Restarter;
-import com.qualcomm.ftccommon.UpdateUI;
-import com.qualcomm.ftccommon.configuration.EditParameters;
-import com.qualcomm.ftccommon.configuration.FtcLoadFileActivity;
-import com.qualcomm.ftccommon.configuration.RobotConfigFile;
-import com.qualcomm.ftccommon.configuration.RobotConfigFileManager;
-import com.qualcomm.ftcrobotcontroller.BuildConfig;
-import com.qualcomm.ftcrobotcontroller.R;
-import com.qualcomm.hardware.HardwareFactory;
-import com.qualcomm.robotcore.eventloop.EventLoopManager;
-import com.qualcomm.robotcore.eventloop.opmode.FtcRobotControllerServiceState;
-import com.qualcomm.robotcore.eventloop.opmode.OpModeRegister;
-import com.qualcomm.robotcore.hardware.configuration.LynxConstants;
-import com.qualcomm.robotcore.hardware.configuration.Utility;
-import com.qualcomm.robotcore.robot.Robot;
-import com.qualcomm.robotcore.robot.RobotState;
-import com.qualcomm.robotcore.util.ClockWarningSource;
-import com.qualcomm.robotcore.util.Device;
-import com.qualcomm.robotcore.util.Dimmer;
-import com.qualcomm.robotcore.util.ImmersiveMode;
-import com.qualcomm.robotcore.util.RobotLog;
-import com.qualcomm.robotcore.util.WebServer;
-import com.qualcomm.robotcore.wifi.NetworkConnection;
-import com.qualcomm.robotcore.wifi.NetworkConnectionFactory;
-import com.qualcomm.robotcore.wifi.NetworkType;
-
-import org.firstinspires.ftc.ftccommon.external.SoundPlayingRobotMonitor;
-import org.firstinspires.ftc.ftccommon.internal.AnnotatedHooksClassFilter;
-import org.firstinspires.ftc.ftccommon.internal.FtcRobotControllerWatchdogService;
-import org.firstinspires.ftc.ftccommon.internal.ProgramAndManageActivity;
-import org.firstinspires.ftc.onbotjava.ExternalLibraries;
-import org.firstinspires.ftc.onbotjava.OnBotJavaHelperImpl;
-import org.firstinspires.ftc.onbotjava.OnBotJavaProgrammingMode;
-import org.firstinspires.ftc.robotcore.external.navigation.MotionDetection;
-import org.firstinspires.ftc.robotcore.internal.hardware.android.AndroidBoard;
-import org.firstinspires.ftc.robotcore.internal.network.DeviceNameManagerFactory;
-import org.firstinspires.ftc.robotcore.internal.network.PreferenceRemoterRC;
-import org.firstinspires.ftc.robotcore.internal.network.StartResult;
-import org.firstinspires.ftc.robotcore.internal.network.WifiDirectChannelChanger;
-import org.firstinspires.ftc.robotcore.internal.network.WifiMuteEvent;
-import org.firstinspires.ftc.robotcore.internal.network.WifiMuteStateMachine;
-import org.firstinspires.ftc.robotcore.internal.opmode.ClassManager;
-import org.firstinspires.ftc.robotcore.internal.opmode.OnBotJavaHelper;
-import org.firstinspires.ftc.robotcore.internal.system.AppAliveNotifier;
-import org.firstinspires.ftc.robotcore.internal.system.AppUtil;
-import org.firstinspires.ftc.robotcore.internal.system.Assert;
-import org.firstinspires.ftc.robotcore.internal.system.PreferencesHelper;
-import org.firstinspires.ftc.robotcore.internal.system.ServiceController;
-import org.firstinspires.ftc.robotcore.internal.ui.ThemedActivity;
-import org.firstinspires.ftc.robotcore.internal.ui.UILocation;
-import org.firstinspires.ftc.robotcore.internal.webserver.RobotControllerWebInfo;
-import org.firstinspires.ftc.robotserver.internal.programmingmode.ProgrammingModeManager;
-import org.firstinspires.inspection.RcInspectionActivity;
-import org.threeten.bp.YearMonth;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.FileNotFoundException;
-import java.util.List;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-@SuppressWarnings("WeakerAccess")
-public class FtcRobotControllerActivity extends Activity
- {
- public static final String TAG = "RCActivity";
- public String getTag() { return TAG; }
-
- private static final int REQUEST_CONFIG_WIFI_CHANNEL = 1;
- private static final int NUM_GAMEPADS = 2;
-
- protected WifiManager.WifiLock wifiLock;
- protected RobotConfigFileManager cfgFileMgr;
-
- private OnBotJavaHelper onBotJavaHelper;
-
- protected ProgrammingModeManager programmingModeManager;
-
- protected UpdateUI.Callback callback;
- protected Context context;
- protected Utility utility;
- protected StartResult prefRemoterStartResult = new StartResult();
- protected StartResult deviceNameStartResult = new StartResult();
- protected PreferencesHelper preferencesHelper;
- protected final SharedPreferencesListener sharedPreferencesListener = new SharedPreferencesListener();
-
- protected ImageButton buttonMenu;
- protected TextView textDeviceName;
- protected TextView textNetworkConnectionStatus;
- protected TextView textRobotStatus;
- protected TextView[] textGamepad = new TextView[NUM_GAMEPADS];
- protected TextView textOpMode;
- protected TextView textErrorMessage;
- protected ImmersiveMode immersion;
-
- protected UpdateUI updateUI;
- protected Dimmer dimmer;
- protected LinearLayout entireScreenLayout;
-
- protected FtcRobotControllerService controllerService;
- protected NetworkType networkType;
-
- protected FtcEventLoop eventLoop;
- protected Queue receivedUsbAttachmentNotifications;
-
- protected WifiMuteStateMachine wifiMuteStateMachine;
- protected MotionDetection motionDetection;
-
- private static boolean permissionsValidated = false;
-
- private WifiDirectChannelChanger wifiDirectChannelChanger;
-
- protected class RobotRestarter implements Restarter {
-
- public void requestRestart() {
- requestRobotRestart();
- }
-
- }
-
- protected boolean serviceShouldUnbind = false;
- protected ServiceConnection connection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- FtcRobotControllerBinder binder = (FtcRobotControllerBinder) service;
- onServiceBind(binder.getService());
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- RobotLog.vv(FtcRobotControllerService.TAG, "%s.controllerService=null", TAG);
- controllerService = null;
- }
- };
-
- @Override
- protected void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
-
- if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) {
- UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
- RobotLog.vv(TAG, "ACTION_USB_DEVICE_ATTACHED: %s", usbDevice.getDeviceName());
-
- if (usbDevice != null) { // paranoia
- // We might get attachment notifications before the event loop is set up, so
- // we hold on to them and pass them along only when we're good and ready.
- if (receivedUsbAttachmentNotifications != null) { // *total* paranoia
- receivedUsbAttachmentNotifications.add(usbDevice);
- passReceivedUsbAttachmentsToEventLoop();
- }
- }
- }
- }
-
- protected void passReceivedUsbAttachmentsToEventLoop() {
- if (this.eventLoop != null) {
- for (;;) {
- UsbDevice usbDevice = receivedUsbAttachmentNotifications.poll();
- if (usbDevice == null)
- break;
- this.eventLoop.onUsbDeviceAttached(usbDevice);
- }
- }
- else {
- // Paranoia: we don't want the pending list to grow without bound when we don't
- // (yet) have an event loop
- while (receivedUsbAttachmentNotifications.size() > 100) {
- receivedUsbAttachmentNotifications.poll();
- }
- }
- }
-
- /**
- * There are cases where a permission may be revoked and the system restart will restart the
- * FtcRobotControllerActivity, instead of the launch activity. Detect when that happens, and throw
- * the device back to the permission validator activity.
- */
- protected boolean enforcePermissionValidator() {
- if (!permissionsValidated) {
- RobotLog.vv(TAG, "Redirecting to permission validator");
- Intent permissionValidatorIntent = new Intent(AppUtil.getDefContext(), PermissionValidatorWrapper.class);
- startActivity(permissionValidatorIntent);
- finish();
- return true;
- } else {
- RobotLog.vv(TAG, "Permissions validated already");
- return false;
- }
- }
-
- public static void setPermissionsValidated() {
- permissionsValidated = true;
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- if (enforcePermissionValidator()) {
- return;
- }
-
- RobotLog.onApplicationStart(); // robustify against onCreate() following onDestroy() but using the same app instance, which apparently does happen
- RobotLog.vv(TAG, "onCreate()");
- ThemedActivity.appAppThemeToActivity(getTag(), this); // do this way instead of inherit to help AppInventor
-
- // Oddly, sometimes after a crash & restart the root activity will be something unexpected, like from the before crash? We don't yet understand
- RobotLog.vv(TAG, "rootActivity is of class %s", AppUtil.getInstance().getRootActivity().getClass().getSimpleName());
- RobotLog.vv(TAG, "launchActivity is of class %s", FtcRobotControllerWatchdogService.launchActivity());
- Assert.assertTrue(FtcRobotControllerWatchdogService.isLaunchActivity(AppUtil.getInstance().getRootActivity()));
- Assert.assertTrue(AppUtil.getInstance().isRobotController());
-
- // Quick check: should we pretend we're not here, and so allow the Lynx to operate as
- // a stand-alone USB-connected module?
- if (LynxConstants.isRevControlHub()) {
- // Double-sure check that we can talk to the DB over the serial TTY
- AndroidBoard.getInstance().getAndroidBoardIsPresentPin().setState(true);
- }
-
- context = this;
- utility = new Utility(this);
-
- DeviceNameManagerFactory.getInstance().start(deviceNameStartResult);
-
- PreferenceRemoterRC.getInstance().start(prefRemoterStartResult);
-
- receivedUsbAttachmentNotifications = new ConcurrentLinkedQueue();
- eventLoop = null;
-
- setContentView(R.layout.activity_ftc_controller);
-
- preferencesHelper = new PreferencesHelper(TAG, context);
- preferencesHelper.writeBooleanPrefIfDifferent(context.getString(R.string.pref_rc_connected), true);
- preferencesHelper.getSharedPreferences().registerOnSharedPreferenceChangeListener(sharedPreferencesListener);
-
- // Check if this RC app is from a later FTC season than what was installed previously
- int ftcSeasonYearOfPreviouslyInstalledRc = preferencesHelper.readInt(getString(R.string.pref_ftc_season_year_of_current_rc), 0);
- int ftcSeasonYearOfCurrentlyInstalledRc = AppUtil.getInstance().getFtcSeasonYear(AppUtil.getInstance().getLocalSdkBuildMonth()).getValue();
- if (ftcSeasonYearOfCurrentlyInstalledRc > ftcSeasonYearOfPreviouslyInstalledRc) {
- preferencesHelper.writeIntPrefIfDifferent(getString(R.string.pref_ftc_season_year_of_current_rc), ftcSeasonYearOfCurrentlyInstalledRc);
- // Since it's a new FTC season, we should reset certain settings back to their default values.
- preferencesHelper.writeBooleanPrefIfDifferent(getString(R.string.pref_warn_about_2_4_ghz_band), true);
- preferencesHelper.writeBooleanPrefIfDifferent(getString(R.string.pref_warn_about_obsolete_software), true);
- preferencesHelper.writeBooleanPrefIfDifferent(getString(R.string.pref_warn_about_mismatched_app_versions), true);
- preferencesHelper.writeBooleanPrefIfDifferent(getString(R.string.pref_warn_about_incorrect_clocks), true);
- }
-
- entireScreenLayout = (LinearLayout) findViewById(R.id.entire_screen);
- buttonMenu = (ImageButton) findViewById(R.id.menu_buttons);
- buttonMenu.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- PopupMenu popupMenu = new PopupMenu(FtcRobotControllerActivity.this, v);
- popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- return onOptionsItemSelected(item); // Delegate to the handler for the hardware menu button
- }
- });
- popupMenu.inflate(R.menu.ftc_robot_controller);
- AnnotatedHooksClassFilter.getInstance().callOnCreateMenuMethods(
- FtcRobotControllerActivity.this, popupMenu.getMenu());
- popupMenu.show();
- }
- });
-
- updateMonitorLayout(getResources().getConfiguration());
-
- BlocksOpMode.setActivityAndWebView(this, (WebView) findViewById(R.id.webViewBlocksRuntime));
-
- ExternalLibraries.getInstance().onCreate();
- onBotJavaHelper = new OnBotJavaHelperImpl();
-
- /*
- * Paranoia as the ClassManagerFactory requires EXTERNAL_STORAGE permissions
- * and we've seen on the DS where the finish() call above does not short-circuit
- * the onCreate() call for the activity and then we crash here because we don't
- * have permissions. So...
- */
- if (permissionsValidated) {
- ClassManager.getInstance().setOnBotJavaClassHelper(onBotJavaHelper);
- ClassManagerFactory.registerFilters();
- ClassManagerFactory.processAllClasses();
- }
-
- cfgFileMgr = new RobotConfigFileManager(this);
-
- // Clean up 'dirty' status after a possible crash
- RobotConfigFile configFile = cfgFileMgr.getActiveConfig();
- if (configFile.isDirty()) {
- configFile.markClean();
- cfgFileMgr.setActiveConfig(false, configFile);
- }
-
- textDeviceName = (TextView) findViewById(R.id.textDeviceName);
- textNetworkConnectionStatus = (TextView) findViewById(R.id.textNetworkConnectionStatus);
- textRobotStatus = (TextView) findViewById(R.id.textRobotStatus);
- textOpMode = (TextView) findViewById(R.id.textOpMode);
- textErrorMessage = (TextView) findViewById(R.id.textErrorMessage);
- textGamepad[0] = (TextView) findViewById(R.id.textGamepad1);
- textGamepad[1] = (TextView) findViewById(R.id.textGamepad2);
- immersion = new ImmersiveMode(getWindow().getDecorView());
- dimmer = new Dimmer(this);
- dimmer.longBright();
-
- programmingModeManager = new ProgrammingModeManager();
- programmingModeManager.register(new ProgrammingWebHandlers());
- programmingModeManager.register(new OnBotJavaProgrammingMode());
-
- updateUI = createUpdateUI();
- callback = createUICallback(updateUI);
-
- PreferenceManager.setDefaultValues(this, R.xml.app_settings, false);
-
- WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
- wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "");
-
- hittingMenuButtonBrightensScreen();
-
- wifiLock.acquire();
- callback.networkConnectionUpdate(NetworkConnection.NetworkEvent.DISCONNECTED);
- readNetworkType();
- ServiceController.startService(FtcRobotControllerWatchdogService.class);
- bindToService();
- RobotLog.logAppInfo();
- RobotLog.logDeviceInfo();
- AndroidBoard.getInstance().logAndroidBoardInfo();
-
- if (preferencesHelper.readBoolean(getString(R.string.pref_wifi_automute), false)) {
- initWifiMute(true);
- }
-
- FtcAboutActivity.setBuildTimeFromBuildConfig(BuildConfig.APP_BUILD_TIME);
-
- // check to see if there is a preferred Wi-Fi to use.
- checkPreferredChannel();
-
- AnnotatedHooksClassFilter.getInstance().callOnCreateMethods(this);
- }
-
- protected UpdateUI createUpdateUI() {
- Restarter restarter = new RobotRestarter();
- UpdateUI result = new UpdateUI(this, dimmer);
- result.setRestarter(restarter);
- result.setTextViews(textNetworkConnectionStatus, textRobotStatus, textGamepad, textOpMode, textErrorMessage, textDeviceName);
- return result;
- }
-
- protected UpdateUI.Callback createUICallback(UpdateUI updateUI) {
- UpdateUI.Callback result = updateUI.new Callback();
- result.setStateMonitor(new SoundPlayingRobotMonitor());
- return result;
- }
-
- @Override
- protected void onStart() {
- super.onStart();
- RobotLog.vv(TAG, "onStart()");
-
- entireScreenLayout.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- dimmer.handleDimTimer();
- return false;
- }
- });
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- RobotLog.vv(TAG, "onResume()");
-
- // In case the user just got back from fixing their clock, refresh ClockWarningSource
- ClockWarningSource.getInstance().onPossibleRcClockUpdate();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- RobotLog.vv(TAG, "onPause()");
- }
-
- @Override
- protected void onStop() {
- // Note: this gets called even when the configuration editor is launched. That is, it gets
- // called surprisingly often. So, we don't actually do much here.
- super.onStop();
- RobotLog.vv(TAG, "onStop()");
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- RobotLog.vv(TAG, "onDestroy()");
-
- shutdownRobot(); // Ensure the robot is put away to bed
- if (callback != null) callback.close();
-
- PreferenceRemoterRC.getInstance().stop(prefRemoterStartResult);
- DeviceNameManagerFactory.getInstance().stop(deviceNameStartResult);
-
- unbindFromService();
- // If the app manually (?) is stopped, then we don't need the auto-starting function (?)
- ServiceController.stopService(FtcRobotControllerWatchdogService.class);
- if (wifiLock != null) wifiLock.release();
- if (preferencesHelper != null) preferencesHelper.getSharedPreferences().unregisterOnSharedPreferenceChangeListener(sharedPreferencesListener);
-
- RobotLog.cancelWriteLogcatToDisk();
-
- AnnotatedHooksClassFilter.getInstance().callOnDestroyMethods(this);
- }
-
- protected void bindToService() {
- readNetworkType();
- Intent intent = new Intent(this, FtcRobotControllerService.class);
- intent.putExtra(NetworkConnectionFactory.NETWORK_CONNECTION_TYPE, networkType);
- serviceShouldUnbind = bindService(intent, connection, Context.BIND_AUTO_CREATE);
- }
-
- protected void unbindFromService() {
- if (serviceShouldUnbind) {
- unbindService(connection);
- serviceShouldUnbind = false;
- }
- }
-
- protected void readNetworkType() {
- // Control hubs are always running the access point model. Everything else, for the time
- // being always runs the Wi-Fi Direct model.
- if (Device.isRevControlHub() == true) {
- networkType = NetworkType.RCWIRELESSAP;
- } else {
- networkType = NetworkType.fromString(preferencesHelper.readString(context.getString(R.string.pref_pairing_kind), NetworkType.globalDefaultAsString()));
- }
-
- // update the app_settings
- preferencesHelper.writeStringPrefIfDifferent(context.getString(R.string.pref_pairing_kind), networkType.toString());
- }
-
- @Override
- public void onWindowFocusChanged(boolean hasFocus) {
- super.onWindowFocusChanged(hasFocus);
-
- if (hasFocus) {
- immersion.hideSystemUI();
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.ftc_robot_controller, menu);
- AnnotatedHooksClassFilter.getInstance().callOnCreateMenuMethods(this, menu);
- return true;
- }
-
- private boolean isRobotRunning() {
- if (controllerService == null) {
- return false;
- }
-
- Robot robot = controllerService.getRobot();
-
- if ((robot == null) || (robot.eventLoopManager == null)) {
- return false;
- }
-
- RobotState robotState = robot.eventLoopManager.state;
-
- if (robotState != RobotState.RUNNING) {
- return false;
- } else {
- return true;
- }
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- int id = item.getItemId();
-
- if (id == R.id.action_program_and_manage) {
- if (isRobotRunning()) {
- Intent programmingModeIntent = new Intent(AppUtil.getDefContext(), ProgramAndManageActivity.class);
- RobotControllerWebInfo webInfo = programmingModeManager.getWebServer().getConnectionInformation();
- programmingModeIntent.putExtra(LaunchActivityConstantsList.RC_WEB_INFO, webInfo.toJson());
- startActivity(programmingModeIntent);
- } else {
- AppUtil.getInstance().showToast(UILocation.ONLY_LOCAL, context.getString(R.string.toastWifiUpBeforeProgrammingMode));
- }
- } else if (id == R.id.action_inspection_mode) {
- Intent inspectionModeIntent = new Intent(AppUtil.getDefContext(), RcInspectionActivity.class);
- startActivity(inspectionModeIntent);
- return true;
- } else if (id == R.id.action_restart_robot) {
- dimmer.handleDimTimer();
- AppUtil.getInstance().showToast(UILocation.BOTH, context.getString(R.string.toastRestartingRobot));
- requestRobotRestart();
- return true;
- }
- else if (id == R.id.action_configure_robot) {
- EditParameters parameters = new EditParameters();
- Intent intentConfigure = new Intent(AppUtil.getDefContext(), FtcLoadFileActivity.class);
- parameters.putIntent(intentConfigure);
- startActivityForResult(intentConfigure, RequestCode.CONFIGURE_ROBOT_CONTROLLER.ordinal());
- }
- else if (id == R.id.action_settings) {
- // historical: this once erroneously used FTC_CONFIGURE_REQUEST_CODE_ROBOT_CONTROLLER
- Intent settingsIntent = new Intent(AppUtil.getDefContext(), FtcRobotControllerSettingsActivity.class);
- startActivityForResult(settingsIntent, RequestCode.SETTINGS_ROBOT_CONTROLLER.ordinal());
- return true;
- }
- else if (id == R.id.action_about) {
- Intent intent = new Intent(AppUtil.getDefContext(), FtcAboutActivity.class);
- startActivity(intent);
- return true;
- }
- else if (id == R.id.action_exit_app) {
-
- //Clear backstack and everything to prevent edge case where VM might be
- //restarted (after it was exited) if more than one activity was on the
- //backstack for some reason.
- finishAffinity();
-
- //For lollipop and up, we can clear ourselves from the recents list too
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
- ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
- List tasks = manager.getAppTasks();
-
- for (ActivityManager.AppTask task : tasks) {
- task.finishAndRemoveTask();
- }
- }
-
- // Allow the user to use the Control Hub operating system's UI, instead of relaunching the app
- AppAliveNotifier.getInstance().disableAppWatchdogUntilNextAppStart();
-
- //Finally, nuke the VM from orbit
- AppUtil.getInstance().exitApplication();
-
- return true;
- }
-
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- // don't destroy assets on screen rotation
- updateMonitorLayout(newConfig);
- }
-
- /**
- * Updates the orientation of monitorContainer (which contains cameraMonitorView)
- * based on the given configuration. Makes the children split the space.
- */
- private void updateMonitorLayout(Configuration configuration) {
- LinearLayout monitorContainer = (LinearLayout) findViewById(R.id.monitorContainer);
- if (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
- // When the phone is landscape, lay out the monitor views horizontally.
- monitorContainer.setOrientation(LinearLayout.HORIZONTAL);
- for (int i = 0; i < monitorContainer.getChildCount(); i++) {
- View view = monitorContainer.getChildAt(i);
- view.setLayoutParams(new LayoutParams(0, LayoutParams.MATCH_PARENT, 1 /* weight */));
- }
- } else {
- // When the phone is portrait, lay out the monitor views vertically.
- monitorContainer.setOrientation(LinearLayout.VERTICAL);
- for (int i = 0; i < monitorContainer.getChildCount(); i++) {
- View view = monitorContainer.getChildAt(i);
- view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 0, 1 /* weight */));
- }
- }
- monitorContainer.requestLayout();
- }
-
- @Override
- protected void onActivityResult(int request, int result, Intent intent) {
- if (request == REQUEST_CONFIG_WIFI_CHANNEL) {
- if (result == RESULT_OK) {
- AppUtil.getInstance().showToast(UILocation.BOTH, context.getString(R.string.toastWifiConfigurationComplete));
- }
- }
- // was some historical confusion about launch codes here, so we err safely
- if (request == RequestCode.CONFIGURE_ROBOT_CONTROLLER.ordinal() || request == RequestCode.SETTINGS_ROBOT_CONTROLLER.ordinal()) {
- // We always do a refresh, whether it was a cancel or an OK, for robustness
- shutdownRobot();
- cfgFileMgr.getActiveConfigAndUpdateUI();
- updateUIAndRequestRobotSetup();
- }
- }
-
- public void onServiceBind(final FtcRobotControllerService service) {
- RobotLog.vv(FtcRobotControllerService.TAG, "%s.controllerService=bound", TAG);
- controllerService = service;
- updateUI.setControllerService(controllerService);
-
- controllerService.setOnBotJavaHelper(onBotJavaHelper);
-
- updateUIAndRequestRobotSetup();
- programmingModeManager.setState(new FtcRobotControllerServiceState() {
- @NonNull
- @Override
- public WebServer getWebServer() {
- return service.getWebServer();
- }
-
- @Nullable
- @Override
- public OnBotJavaHelper getOnBotJavaHelper() {
- return service.getOnBotJavaHelper();
- }
-
- @Override
- public EventLoopManager getEventLoopManager() {
- return service.getRobot().eventLoopManager;
- }
- });
-
- AnnotatedHooksClassFilter.getInstance().callWebHandlerRegistrarMethods(this,
- service.getWebServer().getWebHandlerManager());
- }
-
- private void updateUIAndRequestRobotSetup() {
- if (controllerService != null) {
- callback.networkConnectionUpdate(controllerService.getNetworkConnectionStatus());
- callback.updateRobotStatus(controllerService.getRobotStatus());
- // Only show this first-time toast on headless systems: what we have now on non-headless suffices
- requestRobotSetup(LynxConstants.isRevControlHub()
- ? new Runnable() {
- @Override public void run() {
- showRestartRobotCompleteToast(R.string.toastRobotSetupComplete);
- }
- }
- : null);
- }
- }
-
- private void requestRobotSetup(@Nullable Runnable runOnComplete) {
- if (controllerService == null) return;
-
- RobotConfigFile file = cfgFileMgr.getActiveConfigAndUpdateUI();
- HardwareFactory hardwareFactory = new HardwareFactory(context);
- try {
- hardwareFactory.setXmlPullParser(file.getXml());
- } catch (FileNotFoundException | XmlPullParserException e) {
- RobotLog.ww(TAG, e, "Unable to set configuration file %s. Falling back on noConfig.", file.getName());
- file = RobotConfigFile.noConfig(cfgFileMgr);
- try {
- hardwareFactory.setXmlPullParser(file.getXml());
- cfgFileMgr.setActiveConfigAndUpdateUI(false, file);
- } catch (FileNotFoundException | XmlPullParserException e1) {
- RobotLog.ee(TAG, e1, "Failed to fall back on noConfig");
- }
- }
-
- OpModeRegister userOpModeRegister = createOpModeRegister();
- eventLoop = new FtcEventLoop(hardwareFactory, userOpModeRegister, callback, this);
- FtcEventLoopIdle idleLoop = new FtcEventLoopIdle(hardwareFactory, userOpModeRegister, callback, this);
-
- controllerService.setCallback(callback);
- controllerService.setupRobot(eventLoop, idleLoop, runOnComplete);
-
- passReceivedUsbAttachmentsToEventLoop();
- AndroidBoard.showErrorIfUnknownControlHub();
-
- AnnotatedHooksClassFilter.getInstance().callOnCreateEventLoopMethods(this, eventLoop);
- }
-
- protected OpModeRegister createOpModeRegister() {
- return new FtcOpModeRegister();
- }
-
- private void shutdownRobot() {
- if (controllerService != null) controllerService.shutdownRobot();
- }
-
- private void requestRobotRestart() {
- AppUtil.getInstance().showToast(UILocation.BOTH, AppUtil.getDefContext().getString(R.string.toastRestartingRobot));
- //
- RobotLog.clearGlobalErrorMsg();
- RobotLog.clearGlobalWarningMsg();
- shutdownRobot();
- requestRobotSetup(new Runnable() {
- @Override public void run() {
- showRestartRobotCompleteToast(R.string.toastRestartRobotComplete);
- }
- });
- }
-
- private void showRestartRobotCompleteToast(@StringRes int resid) {
- AppUtil.getInstance().showToast(UILocation.BOTH, AppUtil.getDefContext().getString(resid));
- }
-
- private void checkPreferredChannel() {
- // For P2P network, check to see what preferred channel is.
- if (networkType == NetworkType.WIFIDIRECT) {
- int prefChannel = preferencesHelper.readInt(getString(com.qualcomm.ftccommon.R.string.pref_wifip2p_channel), -1);
- if (prefChannel == -1) {
- prefChannel = 0;
- RobotLog.vv(TAG, "pref_wifip2p_channel: No preferred channel defined. Will use a default value of %d", prefChannel);
- } else {
- RobotLog.vv(TAG, "pref_wifip2p_channel: Found existing preferred channel (%d).", prefChannel);
- }
-
- // attempt to set the preferred channel.
- RobotLog.vv(TAG, "pref_wifip2p_channel: attempting to set preferred channel...");
- wifiDirectChannelChanger = new WifiDirectChannelChanger();
- wifiDirectChannelChanger.changeToChannel(prefChannel);
- }
- }
-
- protected void hittingMenuButtonBrightensScreen() {
- ActionBar actionBar = getActionBar();
- if (actionBar != null) {
- actionBar.addOnMenuVisibilityListener(new ActionBar.OnMenuVisibilityListener() {
- @Override
- public void onMenuVisibilityChanged(boolean isVisible) {
- if (isVisible) {
- dimmer.handleDimTimer();
- }
- }
- });
- }
- }
-
- protected class SharedPreferencesListener implements SharedPreferences.OnSharedPreferenceChangeListener {
- @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- if (key.equals(context.getString(R.string.pref_app_theme))) {
- ThemedActivity.restartForAppThemeChange(getTag(), getString(R.string.appThemeChangeRestartNotifyRC));
- } else if (key.equals(context.getString(R.string.pref_wifi_automute))) {
- if (preferencesHelper.readBoolean(context.getString(R.string.pref_wifi_automute), false)) {
- initWifiMute(true);
- } else {
- initWifiMute(false);
- }
- }
- }
- }
-
- protected void initWifiMute(boolean enable) {
- if (enable) {
- wifiMuteStateMachine = new WifiMuteStateMachine();
- wifiMuteStateMachine.initialize();
- wifiMuteStateMachine.start();
-
- motionDetection = new MotionDetection(2.0, 10);
- motionDetection.startListening();
- motionDetection.registerListener(new MotionDetection.MotionDetectionListener() {
- @Override
- public void onMotionDetected(double vector)
- {
- wifiMuteStateMachine.consumeEvent(WifiMuteEvent.USER_ACTIVITY);
- }
- });
- } else {
- wifiMuteStateMachine.stop();
- wifiMuteStateMachine = null;
- motionDetection.stopListening();
- motionDetection.purgeListeners();
- motionDetection = null;
- }
- }
-
- @Override
- public void onUserInteraction() {
- if (wifiMuteStateMachine != null) {
- wifiMuteStateMachine.consumeEvent(WifiMuteEvent.USER_ACTIVITY);
- }
- }
-}
diff --git a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/PermissionValidatorWrapper.java b/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/PermissionValidatorWrapper.java
deleted file mode 100644
index a0094bc9..00000000
--- a/library/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/PermissionValidatorWrapper.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2018 Craig MacFarlane
- *
- * 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 Craig MacFarlane 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.internal;
-
-import android.Manifest;
-import android.os.Bundle;
-
-import com.qualcomm.ftcrobotcontroller.R;
-
-import org.firstinspires.ftc.robotcore.internal.system.Misc;
-import org.firstinspires.ftc.robotcore.internal.system.PermissionValidatorActivity;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PermissionValidatorWrapper extends PermissionValidatorActivity {
-
- private final String TAG = "PermissionValidatorWrapper";
-
- /*
- * The list of dangerous permissions the robot controller needs.
- */
- protected List robotControllerPermissions = new ArrayList() {{
- add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
- add(Manifest.permission.READ_EXTERNAL_STORAGE);
- add(Manifest.permission.CAMERA);
- add(Manifest.permission.ACCESS_COARSE_LOCATION);
- add(Manifest.permission.ACCESS_FINE_LOCATION);
- add(Manifest.permission.READ_PHONE_STATE);
- }};
-
- private final static Class startApplication = FtcRobotControllerActivity.class;
-
- public String mapPermissionToExplanation(final String permission) {
- if (permission.equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
- return Misc.formatForUser(R.string.permRcWriteExternalStorageExplain);
- } else if (permission.equals(Manifest.permission.READ_EXTERNAL_STORAGE)) {
- return Misc.formatForUser(R.string.permRcReadExternalStorageExplain);
- } else if (permission.equals(Manifest.permission.CAMERA)) {
- return Misc.formatForUser(R.string.permRcCameraExplain);
- } else if (permission.equals(Manifest.permission.ACCESS_COARSE_LOCATION)) {
- return Misc.formatForUser(R.string.permAccessLocationExplain);
- } else if (permission.equals(Manifest.permission.ACCESS_FINE_LOCATION)) {
- return Misc.formatForUser(R.string.permAccessLocationExplain);
- } else if (permission.equals(Manifest.permission.READ_PHONE_STATE)) {
- return Misc.formatForUser(R.string.permReadPhoneState);
- }
- return Misc.formatForUser(R.string.permGenericExplain);
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
-
- permissions = robotControllerPermissions;
- }
-
- protected Class onStartApplication()
- {
- FtcRobotControllerActivity.setPermissionsValidated();
- return startApplication;
- }
-}
diff --git a/library/FtcRobotController/src/main/res/drawable-xhdpi/icon_menu.png b/library/FtcRobotController/src/main/res/drawable-xhdpi/icon_menu.png
deleted file mode 100644
index 6b9e997c..00000000
Binary files a/library/FtcRobotController/src/main/res/drawable-xhdpi/icon_menu.png and /dev/null differ
diff --git a/library/FtcRobotController/src/main/res/drawable-xhdpi/icon_robotcontroller.png b/library/FtcRobotController/src/main/res/drawable-xhdpi/icon_robotcontroller.png
deleted file mode 100644
index 022552f4..00000000
Binary files a/library/FtcRobotController/src/main/res/drawable-xhdpi/icon_robotcontroller.png and /dev/null differ
diff --git a/library/FtcRobotController/src/main/res/layout/activity_ftc_controller.xml b/library/FtcRobotController/src/main/res/layout/activity_ftc_controller.xml
deleted file mode 100644
index 6524f948..00000000
--- a/library/FtcRobotController/src/main/res/layout/activity_ftc_controller.xml
+++ /dev/null
@@ -1,184 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/library/FtcRobotController/src/main/res/menu/ftc_robot_controller.xml b/library/FtcRobotController/src/main/res/menu/ftc_robot_controller.xml
deleted file mode 100644
index 657c1aac..00000000
--- a/library/FtcRobotController/src/main/res/menu/ftc_robot_controller.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-
-
-
diff --git a/library/FtcRobotController/src/main/res/raw/gold.wav b/library/FtcRobotController/src/main/res/raw/gold.wav
deleted file mode 100644
index 3a7baf88..00000000
Binary files a/library/FtcRobotController/src/main/res/raw/gold.wav and /dev/null differ
diff --git a/library/FtcRobotController/src/main/res/raw/silver.wav b/library/FtcRobotController/src/main/res/raw/silver.wav
deleted file mode 100644
index 25918a72..00000000
Binary files a/library/FtcRobotController/src/main/res/raw/silver.wav and /dev/null differ
diff --git a/library/FtcRobotController/src/main/res/values/dimens.xml b/library/FtcRobotController/src/main/res/values/dimens.xml
deleted file mode 100644
index 63f1babc..00000000
--- a/library/FtcRobotController/src/main/res/values/dimens.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
- 16dp
- 5dp
-
-
\ No newline at end of file
diff --git a/library/FtcRobotController/src/main/res/values/strings.xml b/library/FtcRobotController/src/main/res/values/strings.xml
deleted file mode 100644
index 6ea191ed..00000000
--- a/library/FtcRobotController/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-
-
-
-
- FTC Robot Controller
-
-
- Self Inspect
- Program & Manage
- Blocks
- Settings
- Restart Robot
- Configure Robot
- About
- Exit
-
-
- Configuration Complete
- Restarting Robot
- The Robot Controller must be fully up and running before entering Program and Manage Mode.
-
-
-
- - @style/AppThemeRedRC
- - @style/AppThemeGreenRC
- - @style/AppThemeBlueRC
- - @style/AppThemePurpleRC
- - @style/AppThemeOrangeRC
- - @style/AppThemeTealRC
-
-
- pref_ftc_season_year_of_current_rc_new
-
- @string/packageNameRobotController
-
-
diff --git a/library/FtcRobotController/src/main/res/values/styles.xml b/library/FtcRobotController/src/main/res/values/styles.xml
deleted file mode 100644
index 07689c03..00000000
--- a/library/FtcRobotController/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/library/FtcRobotController/src/main/res/xml/app_settings.xml b/library/FtcRobotController/src/main/res/xml/app_settings.xml
deleted file mode 100644
index 58d3aa9c..00000000
--- a/library/FtcRobotController/src/main/res/xml/app_settings.xml
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/library/FtcRobotController/src/main/res/xml/device_filter.xml b/library/FtcRobotController/src/main/res/xml/device_filter.xml
deleted file mode 100644
index 7b75350c..00000000
--- a/library/FtcRobotController/src/main/res/xml/device_filter.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/library/FullPanels/build.gradle.kts b/library/FullPanels/build.gradle.kts
index 5a66b0a0..5096e2c5 100644
--- a/library/FullPanels/build.gradle.kts
+++ b/library/FullPanels/build.gradle.kts
@@ -2,56 +2,45 @@ val pluginNamespace = "com.bylazar.fullpanels"
val pluginVersion = "1.0.12"
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("maven-publish")
+ id("dev.frozenmilk.android-library") version "11.1.0-1.1.1"
id("com.bylazar.svelte-assets")
+ id("dev.frozenmilk.publish") version "0.0.5"
+ id("dev.frozenmilk.doc") version "0.0.5"
+ id("dev.frozenmilk.build-meta-data") version "0.0.2"
}
+android.namespace = pluginNamespace
+
svelteAssets {
- webAppPath = "web"
- buildDirPath = "dist"
- assetsPath = "web/plugins/$pluginNamespace"
+ assetsPath = assetPathForPlugin(pluginNamespace)
}
-android {
- namespace = pluginNamespace
-
- defaultConfig {
- compileSdk = 34
- minSdk = 24
- }
-
- buildTypes {
- getByName("release") {
- isMinifyEnabled = false
- }
- }
+dairyPublishing {
+ gitDir = file("..")
+}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- }
+version = "${dairyPublishing.version}+$pluginVersion"
- kotlinOptions {
- jvmTarget = "11"
- }
+meta {
+ packagePath = pluginNamespace
+ name = "FullPanels"
+ registerField("name", "String", "\"$pluginNamespace\"")
+ registerField("clean", "Boolean") { "${dairyPublishing.clean}" }
+ registerField("gitRef", "String") { "\"${dairyPublishing.gitRef}\"" }
+ registerField("snapshot", "Boolean") { "${dairyPublishing.snapshot}" }
+ registerField("version", "String") { "\"$version\"" }
+}
- publishing {
- singleVariant("release") {}
+ftc {
+ kotlin()
+ sdk {
+ compileOnly(RobotCore)
+ compileOnly(FtcCommon)
+ compileOnly(RobotServer)
}
}
dependencies {
- compileOnly("org.firstinspires.ftc:Inspection:11.0.0")
- compileOnly("org.firstinspires.ftc:Blocks:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotCore:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotServer:11.0.0")
- compileOnly("org.firstinspires.ftc:OnBotJava:11.0.0")
- compileOnly("org.firstinspires.ftc:Hardware:11.0.0")
- compileOnly("org.firstinspires.ftc:FtcCommon:11.0.0")
- compileOnly("org.firstinspires.ftc:Vision:11.0.0")
-
api(project(":Panels"))
api(project(":OpModeControl"))
@@ -77,9 +66,11 @@ afterEvaluate {
create("release") {
from(components["release"])
- groupId = pluginNamespace.substringBeforeLast('.')
+ groupId = pluginNamespace.substringBeforeLast('.') + ".sloth"
artifactId = pluginNamespace.substringAfterLast('.')
- version = pluginVersion
+
+ artifact(dairyDoc.dokkaJavadocJar)
+ artifact(dairyDoc.dokkaHtmlJar)
pom {
description.set("All in one toolbox dashboard for FTC with core plugins.")
@@ -96,12 +87,5 @@ afterEvaluate {
}
}
}
-
- repositories {
- maven {
- name = "localDevRepo"
- url = uri("file:///C:/Users/lazar/Documents/GitHub/ftcontrol-maven/releases")
- }
- }
}
}
diff --git a/library/FullPanels/web/bun.lock b/library/FullPanels/web/bun.lock
index b8db93ae..0d865e4a 100644
--- a/library/FullPanels/web/bun.lock
+++ b/library/FullPanels/web/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "panels-plugin",
diff --git a/library/Gamepad/build.gradle.kts b/library/Gamepad/build.gradle.kts
index bfafbd39..95b22da4 100644
--- a/library/Gamepad/build.gradle.kts
+++ b/library/Gamepad/build.gradle.kts
@@ -2,56 +2,44 @@ val pluginNamespace = "com.bylazar.gamepad"
val pluginVersion = "1.0.4"
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("maven-publish")
+ id("dev.frozenmilk.android-library") version "11.1.0-1.1.1"
id("com.bylazar.svelte-assets")
+ id("dev.frozenmilk.publish") version "0.0.5"
+ id("dev.frozenmilk.doc") version "0.0.5"
+ id("dev.frozenmilk.build-meta-data") version "0.0.2"
}
+android.namespace = pluginNamespace
+
svelteAssets {
- webAppPath = "web"
- buildDirPath = "dist"
- assetsPath = "web/plugins/$pluginNamespace"
+ assetsPath = assetPathForPlugin(pluginNamespace)
}
-android {
- namespace = pluginNamespace
-
- defaultConfig {
- compileSdk = 34
- minSdk = 24
- }
-
- buildTypes {
- getByName("release") {
- isMinifyEnabled = false
- }
- }
+dairyPublishing {
+ gitDir = file("..")
+}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- }
+version = "${dairyPublishing.version}+$pluginVersion"
- kotlinOptions {
- jvmTarget = "11"
- }
+meta {
+ packagePath = pluginNamespace
+ name = "Gamepad"
+ registerField("name", "String", "\"$pluginNamespace\"")
+ registerField("clean", "Boolean") { "${dairyPublishing.clean}" }
+ registerField("gitRef", "String") { "\"${dairyPublishing.gitRef}\"" }
+ registerField("snapshot", "Boolean") { "${dairyPublishing.snapshot}" }
+ registerField("version", "String") { "\"$version\"" }
+}
- publishing {
- singleVariant("release") {}
+ftc {
+ kotlin()
+ sdk {
+ compileOnly(RobotCore)
+ compileOnly(FtcCommon)
}
}
dependencies {
- compileOnly("org.firstinspires.ftc:Inspection:11.0.0")
- compileOnly("org.firstinspires.ftc:Blocks:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotCore:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotServer:11.0.0")
- compileOnly("org.firstinspires.ftc:OnBotJava:11.0.0")
- compileOnly("org.firstinspires.ftc:Hardware:11.0.0")
- compileOnly("org.firstinspires.ftc:FtcCommon:11.0.0")
- compileOnly("org.firstinspires.ftc:Vision:11.0.0")
-
compileOnly(project(":Panels"))
}
@@ -61,9 +49,11 @@ afterEvaluate {
create("release") {
from(components["release"])
- groupId = pluginNamespace.substringBeforeLast('.')
+ groupId = pluginNamespace.substringBeforeLast('.') + ".sloth"
artifactId = pluginNamespace.substringAfterLast('.')
- version = pluginVersion
+
+ artifact(dairyDoc.dokkaJavadocJar)
+ artifact(dairyDoc.dokkaHtmlJar)
pom {
description.set("Panels Gamepad Plugin")
@@ -80,12 +70,5 @@ afterEvaluate {
}
}
}
-
- repositories {
- maven {
- name = "localDevRepo"
- url = uri("file:///C:/Users/lazar/Documents/GitHub/ftcontrol-maven/releases")
- }
- }
}
}
diff --git a/library/Gamepad/web/bun.lock b/library/Gamepad/web/bun.lock
index b8db93ae..0d865e4a 100644
--- a/library/Gamepad/web/bun.lock
+++ b/library/Gamepad/web/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "panels-plugin",
diff --git a/library/Graph/build.gradle.kts b/library/Graph/build.gradle.kts
index 4cad699a..86e65549 100644
--- a/library/Graph/build.gradle.kts
+++ b/library/Graph/build.gradle.kts
@@ -2,43 +2,41 @@ val pluginNamespace = "com.bylazar.graph"
val pluginVersion = "1.0.4"
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("maven-publish")
+ id("dev.frozenmilk.android-library") version "11.1.0-1.1.1"
id("com.bylazar.svelte-assets")
+ id("dev.frozenmilk.publish") version "0.0.5"
+ id("dev.frozenmilk.doc") version "0.0.5"
+ id("dev.frozenmilk.build-meta-data") version "0.0.2"
}
+android.namespace = pluginNamespace
+
svelteAssets {
- webAppPath = "web"
- buildDirPath = "dist"
- assetsPath = "web/plugins/$pluginNamespace"
+ assetsPath = assetPathForPlugin(pluginNamespace)
}
-android {
- namespace = pluginNamespace
-
- defaultConfig {
- compileSdk = 34
- minSdk = 24
- }
-
- buildTypes {
- getByName("release") {
- isMinifyEnabled = false
- }
- }
+dairyPublishing {
+ gitDir = file("..")
+}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- }
+version = "${dairyPublishing.version}+$pluginVersion"
- kotlinOptions {
- jvmTarget = "11"
- }
+meta {
+ packagePath = pluginNamespace
+ name = "Graph"
+ registerField("name", "String", "\"$pluginNamespace\"")
+ registerField("clean", "Boolean") { "${dairyPublishing.clean}" }
+ registerField("gitRef", "String") { "\"${dairyPublishing.gitRef}\"" }
+ registerField("snapshot", "Boolean") { "${dairyPublishing.snapshot}" }
+ registerField("version", "String") { "\"$version\"" }
+}
- publishing {
- singleVariant("release") {}
+ftc {
+ kotlin()
+ sdk {
+ compileOnly(RobotCore)
+ compileOnly(FtcCommon)
+ compileOnly(RobotServer)
}
}
@@ -61,9 +59,11 @@ afterEvaluate {
create("release") {
from(components["release"])
- groupId = pluginNamespace.substringBeforeLast('.')
+ groupId = pluginNamespace.substringBeforeLast('.') + ".sloth"
artifactId = pluginNamespace.substringAfterLast('.')
- version = pluginVersion
+
+ artifact(dairyDoc.dokkaJavadocJar)
+ artifact(dairyDoc.dokkaHtmlJar)
pom {
description.set("Panels Graph Plugin")
@@ -80,12 +80,5 @@ afterEvaluate {
}
}
}
-
- repositories {
- maven {
- name = "localDevRepo"
- url = uri("file:///C:/Users/lazar/Documents/GitHub/ftcontrol-maven/releases")
- }
- }
}
}
diff --git a/library/Graph/web/bun.lock b/library/Graph/web/bun.lock
index bfc69e3b..0832e7d8 100644
--- a/library/Graph/web/bun.lock
+++ b/library/Graph/web/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "panels-plugin",
diff --git a/library/Lights/build.gradle.kts b/library/Lights/build.gradle.kts
index 46942d59..d0bc98fc 100644
--- a/library/Lights/build.gradle.kts
+++ b/library/Lights/build.gradle.kts
@@ -2,56 +2,45 @@ val pluginNamespace = "com.bylazar.lights"
val pluginVersion = "1.0.3"
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("maven-publish")
+ id("dev.frozenmilk.android-library") version "11.1.0-1.1.1"
id("com.bylazar.svelte-assets")
+ id("dev.frozenmilk.publish") version "0.0.5"
+ id("dev.frozenmilk.doc") version "0.0.5"
+ id("dev.frozenmilk.build-meta-data") version "0.0.2"
}
+android.namespace = pluginNamespace
+
svelteAssets {
- webAppPath = "web"
- buildDirPath = "dist"
- assetsPath = "web/plugins/$pluginNamespace"
+ assetsPath = assetPathForPlugin(pluginNamespace)
}
-android {
- namespace = pluginNamespace
-
- defaultConfig {
- compileSdk = 34
- minSdk = 24
- }
-
- buildTypes {
- getByName("release") {
- isMinifyEnabled = false
- }
- }
+dairyPublishing {
+ gitDir = file("..")
+}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- }
+version = "${dairyPublishing.version}+$pluginVersion"
- kotlinOptions {
- jvmTarget = "11"
- }
+meta {
+ packagePath = pluginNamespace
+ name = "Lights"
+ registerField("name", "String", "\"$pluginNamespace\"")
+ registerField("clean", "Boolean") { "${dairyPublishing.clean}" }
+ registerField("gitRef", "String") { "\"${dairyPublishing.gitRef}\"" }
+ registerField("snapshot", "Boolean") { "${dairyPublishing.snapshot}" }
+ registerField("version", "String") { "\"$version\"" }
+}
- publishing {
- singleVariant("release") {}
+ftc {
+ kotlin()
+ sdk {
+ compileOnly(RobotCore)
+ compileOnly(FtcCommon)
+ compileOnly(RobotServer)
}
}
dependencies {
- compileOnly("org.firstinspires.ftc:Inspection:11.0.0")
- compileOnly("org.firstinspires.ftc:Blocks:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotCore:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotServer:11.0.0")
- compileOnly("org.firstinspires.ftc:OnBotJava:11.0.0")
- compileOnly("org.firstinspires.ftc:Hardware:11.0.0")
- compileOnly("org.firstinspires.ftc:FtcCommon:11.0.0")
- compileOnly("org.firstinspires.ftc:Vision:11.0.0")
-
compileOnly(project(":Panels"))
}
@@ -61,9 +50,11 @@ afterEvaluate {
create("release") {
from(components["release"])
- groupId = pluginNamespace.substringBeforeLast('.')
+ groupId = pluginNamespace.substringBeforeLast('.') + ".sloth"
artifactId = pluginNamespace.substringAfterLast('.')
- version = pluginVersion
+
+ artifact(dairyDoc.dokkaJavadocJar)
+ artifact(dairyDoc.dokkaHtmlJar)
pom {
description.set("Panels Telemetry Plugin")
@@ -80,12 +71,5 @@ afterEvaluate {
}
}
}
-
- repositories {
- maven {
- name = "localDevRepo"
- url = uri("file:///C:/Users/lazar/Documents/GitHub/ftcontrol-maven/releases")
- }
- }
}
}
diff --git a/library/Lights/web/bun.lock b/library/Lights/web/bun.lock
index b8db93ae..0d865e4a 100644
--- a/library/Lights/web/bun.lock
+++ b/library/Lights/web/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "panels-plugin",
diff --git a/library/LimelightProxy/build.gradle.kts b/library/LimelightProxy/build.gradle.kts
index 6f51a5ce..c6a87df9 100644
--- a/library/LimelightProxy/build.gradle.kts
+++ b/library/LimelightProxy/build.gradle.kts
@@ -1,63 +1,49 @@
-import org.gradle.kotlin.dsl.implementation
-
val pluginNamespace = "com.bylazar.limelightproxy"
val pluginVersion = "1.0.4"
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("maven-publish")
+ id("dev.frozenmilk.android-library") version "11.1.0-1.1.1"
id("com.bylazar.svelte-assets")
+ id("dev.frozenmilk.publish") version "0.0.5"
+ id("dev.frozenmilk.doc") version "0.0.5"
+ id("dev.frozenmilk.build-meta-data") version "0.0.2"
}
+android.namespace = pluginNamespace
+
svelteAssets {
- webAppPath = "web"
- buildDirPath = "dist"
- assetsPath = "web/plugins/$pluginNamespace"
+ assetsPath = assetPathForPlugin(pluginNamespace)
}
-android {
- namespace = pluginNamespace
-
- defaultConfig {
- compileSdk = 34
- minSdk = 24
- }
-
- buildTypes {
- getByName("release") {
- isMinifyEnabled = false
- }
- }
+dairyPublishing {
+ gitDir = file("..")
+}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- }
+version = "${dairyPublishing.version}+$pluginVersion"
- kotlinOptions {
- jvmTarget = "11"
- }
+meta {
+ packagePath = pluginNamespace
+ name = "LimelightProxy"
+ registerField("name", "String", "\"$pluginNamespace\"")
+ registerField("clean", "Boolean") { "${dairyPublishing.clean}" }
+ registerField("gitRef", "String") { "\"$version\"" }
+ registerField("snapshot", "Boolean") { "${dairyPublishing.snapshot}" }
+ registerField("version", "String") { "\"${dairyPublishing.version}\"" }
+}
- publishing {
- singleVariant("release") {}
+ftc {
+ kotlin()
+ sdk {
+ compileOnly(RobotCore)
+ compileOnly(FtcCommon)
+ compileOnly(RobotServer)
}
}
dependencies {
- compileOnly("org.firstinspires.ftc:Inspection:11.0.0")
- compileOnly("org.firstinspires.ftc:Blocks:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotCore:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotServer:11.0.0")
- compileOnly("org.firstinspires.ftc:OnBotJava:11.0.0")
- compileOnly("org.firstinspires.ftc:Hardware:11.0.0")
- compileOnly("org.firstinspires.ftc:FtcCommon:11.0.0")
- compileOnly("org.firstinspires.ftc:Vision:11.0.0")
-
compileOnly(project(":Panels"))
implementation("com.squareup.okhttp3:okhttp:4.10.0")
-
}
afterEvaluate {
@@ -66,9 +52,11 @@ afterEvaluate {
create("release") {
from(components["release"])
- groupId = pluginNamespace.substringBeforeLast('.')
+ groupId = pluginNamespace.substringBeforeLast('.') + ".sloth"
artifactId = pluginNamespace.substringAfterLast('.')
- version = pluginVersion
+
+ artifact(dairyDoc.dokkaJavadocJar)
+ artifact(dairyDoc.dokkaHtmlJar)
pom {
description.set("Panels Limelight Proxy Plugin")
@@ -85,12 +73,5 @@ afterEvaluate {
}
}
}
-
- repositories {
- maven {
- name = "localDevRepo"
- url = uri("file:///C:/Users/lazar/Documents/GitHub/ftcontrol-maven/releases")
- }
- }
}
}
diff --git a/library/LimelightProxy/web/bun.lock b/library/LimelightProxy/web/bun.lock
index b8db93ae..0d865e4a 100644
--- a/library/LimelightProxy/web/bun.lock
+++ b/library/LimelightProxy/web/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "panels-plugin",
diff --git a/library/OpModeControl/build.gradle.kts b/library/OpModeControl/build.gradle.kts
index 9987f5fa..4febced0 100644
--- a/library/OpModeControl/build.gradle.kts
+++ b/library/OpModeControl/build.gradle.kts
@@ -2,56 +2,48 @@ val pluginNamespace = "com.bylazar.opmodecontrol"
val pluginVersion = "1.0.3"
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("maven-publish")
+ id("dev.frozenmilk.android-library") version "11.1.0-1.1.1"
id("com.bylazar.svelte-assets")
+ id("dev.frozenmilk.publish") version "0.0.5"
+ id("dev.frozenmilk.doc") version "0.0.5"
+ id("dev.frozenmilk.build-meta-data") version "0.0.2"
}
+android.namespace = pluginNamespace
+
svelteAssets {
- webAppPath = "web"
- buildDirPath = "dist"
- assetsPath = "web/plugins/$pluginNamespace"
+ assetsPath = assetPathForPlugin(pluginNamespace)
}
-android {
- namespace = pluginNamespace
+dairyPublishing {
+ gitDir = file("..")
+}
- defaultConfig {
- compileSdk = 34
- minSdk = 24
- }
+version = "${dairyPublishing.version}+$pluginVersion"
- buildTypes {
- getByName("release") {
- isMinifyEnabled = false
- }
- }
+meta {
+ packagePath = pluginNamespace
+ name = "OpModeControl"
+ registerField("name", "String", "\"$pluginNamespace\"")
+ registerField("clean", "Boolean") { "${dairyPublishing.clean}" }
+ registerField("gitRef", "String") { "\"${dairyPublishing.gitRef}\"" }
+ registerField("snapshot", "Boolean") { "${dairyPublishing.snapshot}" }
+ registerField("version", "String") { "\"${dairyPublishing.version}\"" }
+}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
+ftc {
+ kotlin()
+ sdk {
+ compileOnly(RobotCore)
+ compileOnly(FtcCommon)
+ compileOnly(RobotServer)
}
-
- kotlinOptions {
- jvmTarget = "11"
- }
-
- publishing {
- singleVariant("release") {}
+ dairy {
+ implementation(Sloth)
}
}
dependencies {
- compileOnly("org.firstinspires.ftc:Inspection:11.0.0")
- compileOnly("org.firstinspires.ftc:Blocks:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotCore:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotServer:11.0.0")
- compileOnly("org.firstinspires.ftc:OnBotJava:11.0.0")
- compileOnly("org.firstinspires.ftc:Hardware:11.0.0")
- compileOnly("org.firstinspires.ftc:FtcCommon:11.0.0")
- compileOnly("org.firstinspires.ftc:Vision:11.0.0")
-
compileOnly(project(":Panels"))
}
@@ -61,9 +53,11 @@ afterEvaluate {
create("release") {
from(components["release"])
- groupId = pluginNamespace.substringBeforeLast('.')
+ groupId = pluginNamespace.substringBeforeLast('.') + ".sloth"
artifactId = pluginNamespace.substringAfterLast('.')
- version = pluginVersion
+
+ artifact(dairyDoc.dokkaHtmlJar)
+ artifact(dairyDoc.dokkaJavadocJar)
pom {
description.set("Panels OpModeControl Plugin")
@@ -80,12 +74,5 @@ afterEvaluate {
}
}
}
-
- repositories {
- maven {
- name = "localDevRepo"
- url = uri("file:///C:/Users/lazar/Documents/GitHub/ftcontrol-maven/releases")
- }
- }
}
}
diff --git a/library/OpModeControl/src/main/java/com/bylazar/opmodecontrol/OpModeControlPlugin.kt b/library/OpModeControl/src/main/java/com/bylazar/opmodecontrol/OpModeControlPlugin.kt
index 98b7fbf5..dea76d61 100644
--- a/library/OpModeControl/src/main/java/com/bylazar/opmodecontrol/OpModeControlPlugin.kt
+++ b/library/OpModeControl/src/main/java/com/bylazar/opmodecontrol/OpModeControlPlugin.kt
@@ -1,7 +1,6 @@
package com.bylazar.opmodecontrol
import android.content.Context
-import android.os.SystemClock
import com.bylazar.panels.Panels
import com.bylazar.panels.plugins.BasePluginConfig
import com.bylazar.panels.plugins.Plugin
@@ -9,22 +8,35 @@ import com.bylazar.panels.server.Socket
import com.qualcomm.ftccommon.FtcEventLoop
import com.qualcomm.robotcore.eventloop.opmode.OpMode
import com.qualcomm.robotcore.eventloop.opmode.OpModeManagerImpl
+import dev.frozenmilk.sinister.Scanner
+import dev.frozenmilk.sinister.sdk.apphooks.SDKOpModeRegistrar
+import dev.frozenmilk.sinister.sdk.opmodes.OpModeScanner
+import dev.frozenmilk.sinister.sdk.opmodes.SinisterRegisteredOpModes
+import dev.frozenmilk.sinister.targeting.NarrowSearch
+import dev.frozenmilk.util.graph.rule.dependsOn
+import dev.frozenmilk.util.graph.rule.dependsOnClass
import org.firstinspires.ftc.robotcore.internal.opmode.OpModeMeta
-import org.firstinspires.ftc.robotcore.internal.opmode.RegisteredOpModes
import java.lang.ref.WeakReference
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledFuture
import java.util.concurrent.TimeUnit
-open class OpModeControlPluginConfig : BasePluginConfig() {
-}
+open class OpModeControlPluginConfig : BasePluginConfig() {}
+
+object Plugin : Plugin(OpModeControlPluginConfig()), Scanner {
+ val opModeList: List
+ get() = SinisterRegisteredOpModes.opModes.mapNotNull { opModeMeta ->
+ if (opModeMeta.flavor == OpModeMeta.Flavor.SYSTEM) null
+ else OpModeDetails(
+ name = opModeMeta.name,
+ group = opModeMeta.group,
+ flavour = opModeMeta.flavor,
+ source = opModeMeta.source ?: OpModeMeta.Source.ANDROID_STUDIO,
+ defaultGroup = OpModeMeta.DefaultGroup,
+ autoTransition = opModeMeta.autoTransition ?: ""
+ )
+ }.sortedWith(compareBy({ it.group }, { it.name }))
-object Plugin : Plugin(OpModeControlPluginConfig()) {
- var opModeList: MutableList = mutableListOf()
- set(value) {
- field = value
- send("opModesList", OpModesList(value))
- }
var status = OpModeStatus.STOPPED
var activeOpMode: OpMode? = null
var activeOpModeStartTimestamp: Long? = null
@@ -58,6 +70,7 @@ object Plugin : Plugin(OpModeControlPluginConfig()) {
private val scheduler = Executors.newSingleThreadScheduledExecutor { r ->
Thread(r, "OpModeControl-Ticker")
}
+
@Volatile
private var tickTask: ScheduledFuture<*>? = null
@@ -107,8 +120,7 @@ object Plugin : Plugin(OpModeControlPluginConfig()) {
}
override fun onRegister(
- panelsInstance: Panels,
- context: Context
+ panelsInstance: Panels, context: Context
) {
}
@@ -122,9 +134,6 @@ object Plugin : Plugin(OpModeControlPluginConfig()) {
opModeManagerRef = WeakReference(o)
activeOpMode = null
activeOpModeName = ""
- opModeList.clear()
- val t = Thread(FetcherRoutine())
- t.start()
activeOpModeStartTimestamp = null
}
@@ -170,39 +179,32 @@ object Plugin : Plugin(OpModeControlPluginConfig()) {
sendActiveOpMode()
}
- class FetcherRoutine : Runnable {
- override fun run() {
- RegisteredOpModes.getInstance().waitOpModesRegistered()
-
- var list = ArrayList()
- for (opModeMeta in RegisteredOpModes.getInstance().opModes) {
- if (opModeMeta.flavor != OpModeMeta.Flavor.SYSTEM) {
- list.add(
- OpModeDetails(
- name = opModeMeta.name,
- group = opModeMeta.group,
- flavour = opModeMeta.flavor,
- source = opModeMeta.source ?: OpModeMeta.Source.ANDROID_STUDIO,
- defaultGroup = OpModeMeta.DefaultGroup,
- autoTransition = opModeMeta.autoTransition ?: ""
- )
- )
- }
- }
-
- opModeList = list.sortedWith(compareBy({ it.group }, { it.name })).toMutableList()
- log("OpModes: ${opModeList.joinToString(", ", transform = { it.name })}")
-
- send("opModesList", OpModesList(opModeList))
- sendActiveOpMode()
- }
+ override fun onEnablePanels() {
}
+ override fun onDisablePanels() {
+ }
- override fun onEnablePanels() {
+ override val loadAdjacencyRule =
+ dependsOnClass(OpModeScanner::class.java).and(dependsOn(SDKOpModeRegistrar))
+ override val unloadAdjacencyRule =
+ dependsOnClass(OpModeScanner::class.java).and(dependsOn(SDKOpModeRegistrar))
+ override val targets = NarrowSearch()
+
+ override fun scan(loader: ClassLoader, cls: Class<*>) {}
+ override fun afterScan(loader: ClassLoader) {
+ val opModeList = opModeList
+ log("OpModes: ${opModeList.joinToString(", ", transform = { it.name })}")
+ send("opModesList", OpModesList(opModeList))
+ sendActiveOpMode()
}
- override fun onDisablePanels() {
+ override fun unload(loader: ClassLoader, cls: Class<*>) {}
+ override fun afterUnload(loader: ClassLoader) {
+ val opModeList = opModeList
+ log("OpModes: ${opModeList.joinToString(", ", transform = { it.name })}")
+ send("opModesList", OpModesList(opModeList))
+ sendActiveOpMode()
}
}
\ No newline at end of file
diff --git a/library/OpModeControl/web/bun.lock b/library/OpModeControl/web/bun.lock
index b8db93ae..0d865e4a 100644
--- a/library/OpModeControl/web/bun.lock
+++ b/library/OpModeControl/web/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "panels-plugin",
diff --git a/library/Panels/build.gradle.kts b/library/Panels/build.gradle.kts
index e369dbe4..38bf6301 100644
--- a/library/Panels/build.gradle.kts
+++ b/library/Panels/build.gradle.kts
@@ -1,77 +1,59 @@
+val pluginNamespace = "com.bylazar.panels"
+val pluginVersion = "1.0.5"
+
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("maven-publish")
+ id("dev.frozenmilk.android-library") version "11.1.0-1.1.1"
id("com.bylazar.svelte-assets")
+ id("dev.frozenmilk.publish") version "0.0.5"
+ id("dev.frozenmilk.doc") version "0.0.5"
+ id("dev.frozenmilk.build-meta-data") version "0.0.2"
}
-val pluginNamespace = "com.bylazar.panels"
-val pluginVersion = "1.0.5"
+android.namespace = pluginNamespace
svelteAssets {
- webAppPath = "web"
- buildDirPath = "build"
assetsPath = "web"
+ buildDirPath = "build"
}
-android {
- namespace = "com.bylazar.panels"
-
- defaultConfig {
- compileSdk = 34
- minSdk = 24
-
- testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
- consumerProguardFiles("consumer-rules.pro")
- }
-
- buildTypes {
- getByName("release") {
- isMinifyEnabled = false
- proguardFiles(
- getDefaultProguardFile("proguard-android-optimize.txt"),
- "proguard-rules.pro"
- )
- }
- }
+dairyPublishing {
+ gitDir = file("..")
+}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- }
+version = "${dairyPublishing.version}+$pluginVersion"
- kotlinOptions {
- jvmTarget = "11"
- }
+meta {
+ packagePath = pluginNamespace
+ name = "Panels"
+ registerField("name", "String", "\"$pluginNamespace\"")
+ registerField("clean", "Boolean") { "${dairyPublishing.clean}" }
+ registerField("gitRef", "String") { "\"${dairyPublishing.gitRef}\"" }
+ registerField("snapshot", "Boolean") { "${dairyPublishing.snapshot}" }
+ registerField("version", "String") { "\"$version\"" }
+}
- publishing {
- singleVariant("release") {}
+ftc {
+ kotlin()
+ sdk {
+ compileOnly(RobotCore)
+ compileOnly(FtcCommon)
+ compileOnly(RobotServer)
+ implementation(appcompat)
}
}
dependencies {
- implementation("androidx.core:core-ktx:1.13.1")
- implementation("androidx.appcompat:appcompat:1.2.0")
- implementation("com.google.android.material:material:1.12.0")
+ implementation("androidx.core:core-ktx:1.2.0")
testImplementation("junit:junit:4.13.2")
- androidTestImplementation("androidx.test.ext:junit:1.2.1")
- androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
-
- compileOnly("org.firstinspires.ftc:Inspection:11.0.0")
- compileOnly("org.firstinspires.ftc:Blocks:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotCore:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotServer:11.0.0")
- compileOnly("org.firstinspires.ftc:OnBotJava:11.0.0")
- compileOnly("org.firstinspires.ftc:Hardware:11.0.0")
- compileOnly("org.firstinspires.ftc:FtcCommon:11.0.0")
- compileOnly("org.firstinspires.ftc:Vision:11.0.0")
+ androidTestImplementation("androidx.test.ext:junit:1.1.5")
+ //androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
implementation("org.nanohttpd:nanohttpd-websocket:2.3.1") {
exclude(module = "nanohttpd")
}
- implementation("org.jetbrains.kotlin:kotlin-reflect:1.9.23")
+ implementation("org.jetbrains.kotlin:kotlin-reflect:2.3.0")
implementation("org.tukaani:xz:1.9")
}
@@ -82,9 +64,11 @@ afterEvaluate {
create("release") {
from(components["release"])
- groupId = pluginNamespace.substringBeforeLast('.')
+ groupId = pluginNamespace.substringBeforeLast('.') + ".sloth"
artifactId = pluginNamespace.substringAfterLast('.')
- version = pluginVersion
+
+ artifact(dairyDoc.dokkaJavadocJar)
+ artifact(dairyDoc.dokkaHtmlJar)
pom {
description.set("All in one toolbox dashboard for FTC.")
@@ -101,12 +85,5 @@ afterEvaluate {
}
}
}
-
- repositories {
- maven {
- name = "localDevRepo"
- url = uri("file:///C:/Users/lazar/Documents/GitHub/ftcontrol-maven/releases")
- }
- }
}
}
diff --git a/library/Panels/src/androidTest/java/com/bylazar/panels/TestCompression.kt b/library/Panels/src/androidTest/java/com/bylazar/panels/TestCompression.kt
index 4a20eb27..9fd2a6f3 100644
--- a/library/Panels/src/androidTest/java/com/bylazar/panels/TestCompression.kt
+++ b/library/Panels/src/androidTest/java/com/bylazar/panels/TestCompression.kt
@@ -62,9 +62,8 @@ class TestCompression {
return output.toByteArray()
}
- private fun decompressGzip(input: ByteArray, originalSize: Int): ByteArray {
- val inputStream = ByteArrayInputStream(input)
- return GZIPInputStream(inputStream).readAllBytes()
+ private fun decompressGzip(input: ByteArray, originalSize: Int) = ByteArrayInputStream(input).use {
+ GZIPInputStream(it).readBytes()
}
fun compressLzma(input: ByteArray): ByteArray {
@@ -74,9 +73,8 @@ class TestCompression {
return baos.toByteArray()
}
- fun decompressLzma(input: ByteArray): ByteArray {
- val bais = ByteArrayInputStream(input)
- return LZMAInputStream(bais).readAllBytes()
+ fun decompressLzma(input: ByteArray) = ByteArrayInputStream(input).use {
+ LZMAInputStream(it).readBytes()
}
fun compressDeflate(input: ByteArray): ByteArray {
diff --git a/library/Panels/src/main/java/com/bylazar/panels/Logger.kt b/library/Panels/src/main/java/com/bylazar/panels/Logger.kt
index 64fe4673..58555df7 100644
--- a/library/Panels/src/main/java/com/bylazar/panels/Logger.kt
+++ b/library/Panels/src/main/java/com/bylazar/panels/Logger.kt
@@ -1,5 +1,7 @@
package com.bylazar.panels
+import com.qualcomm.robotcore.util.RobotLog
+
object Logger {
const val REFLECTION_PREFIX = "Reflection"
const val SOCKET_PREFIX = "Socket"
@@ -7,8 +9,8 @@ object Logger {
const val PLUGINS_PREFIX = "Plugins"
const val CORE_PREFIX = "Core"
- private fun getCallerClassName(): String {
- if(!Panels.config.enableClassCallerLogs) return "Disabled"
+ private fun getCallerClassName(): String? {
+ if(!Panels.config.enableClassCallerLogs) return null
return Throwable()
.stackTrace
.firstOrNull { !it.className.contains("com.bylazar.panels.Logger") }
@@ -17,14 +19,20 @@ object Logger {
?: "Unknown"
}
+ private fun logCallerClass(message: String) =
+ getCallerClassName()?.let { "($it): $message" } ?: message
+
fun log(prefix: String, message: String) {
if(!Panels.config.enableLogs) return
- println("PANELS: ${prefix.uppercase()}: (${getCallerClassName()}): $message")
+ RobotLog.ii("Panels::$prefix", logCallerClass(message))
}
fun error(prefix: String, message: String) {
- if(!Panels.config.enableLogs) return
- println("PANELS: ${prefix.uppercase()}: (${getCallerClassName()}): ERROR: $message")
+ RobotLog.ee("Panels::$prefix", logCallerClass(message))
+ }
+
+ fun error(prefix: String, message: String, e: Throwable) {
+ RobotLog.ee("Panels@$prefix", e, logCallerClass(message))
}
fun reflectionLog(message: String) = log(REFLECTION_PREFIX, message)
@@ -32,13 +40,16 @@ object Logger {
fun socketLog(message: String) = log(SOCKET_PREFIX, message)
fun socketError(message: String) = error(SOCKET_PREFIX, message)
+ fun socketError(message: String, e: Throwable) = error(SOCKET_PREFIX, message, e)
fun serverLog(message: String) = log(SERVER_PREFIX, message)
fun serverError(message: String) = error(SERVER_PREFIX, message)
+ fun serverError(message: String, e: Throwable) = error(SERVER_PREFIX, message, e)
fun pluginsLog(message: String) = log(PLUGINS_PREFIX, message)
fun pluginsError(message: String) = error(PLUGINS_PREFIX, message)
fun coreLog(message: String) = log(CORE_PREFIX, message)
fun coreError(message: String) = error(CORE_PREFIX, message)
+ fun coreError(message: String, e: Throwable) = error(CORE_PREFIX, message, e)
}
\ No newline at end of file
diff --git a/library/Panels/src/main/java/com/bylazar/panels/Panels.kt b/library/Panels/src/main/java/com/bylazar/panels/Panels.kt
index 9f86fae5..7957d714 100644
--- a/library/Panels/src/main/java/com/bylazar/panels/Panels.kt
+++ b/library/Panels/src/main/java/com/bylazar/panels/Panels.kt
@@ -1,19 +1,16 @@
package com.bylazar.panels
import android.content.Context
-import androidx.core.app.PendingIntentCompat.send
-import com.bylazar.panels.core.TextHandler
import com.bylazar.panels.core.OpModeHandler
import com.bylazar.panels.core.PreferencesHandler
+import com.bylazar.panels.core.TextHandler
import com.bylazar.panels.plugins.PluginsManager
-import com.bylazar.panels.plugins.PluginsManager.contextRef
import com.bylazar.panels.reflection.ClassFinder
import com.bylazar.panels.server.Socket
import com.bylazar.panels.server.StaticServer
import com.qualcomm.ftccommon.FtcEventLoop
import com.qualcomm.robotcore.eventloop.opmode.OpMode
import com.qualcomm.robotcore.eventloop.opmode.OpModeManager
-import com.qualcomm.robotcore.eventloop.opmode.OpModeManagerImpl
import com.qualcomm.robotcore.eventloop.opmode.OpModeManagerNotifier.Notifications
import com.qualcomm.robotcore.eventloop.opmode.OpModeRegistrar
import com.qualcomm.robotcore.util.WebHandlerManager
@@ -22,10 +19,7 @@ import org.firstinspires.ftc.ftccommon.external.OnCreateEventLoop
import org.firstinspires.ftc.ftccommon.external.OnDestroy
import org.firstinspires.ftc.ftccommon.external.WebHandlerRegistrar
import org.firstinspires.ftc.ftccommon.internal.FtcRobotControllerWatchdogService
-import org.firstinspires.ftc.robotcore.internal.opmode.OpModeMeta
-import org.firstinspires.ftc.robotcore.internal.opmode.RegisteredOpModes
import org.firstinspires.ftc.robotcore.internal.system.AppUtil
-import java.lang.ref.WeakReference
object Panels : Notifications {
@@ -83,7 +77,7 @@ object Panels : Notifications {
server = StaticServer(context, 8001, "web")
socket = Socket(8002)
} catch (e: Exception) {
- Logger.coreLog("Failed to start webserver: " + e.message)
+ Logger.coreError("Failed to start webserver", e)
}
if (PreferencesHandler.isEnabled) {
diff --git a/library/Panels/src/main/java/com/bylazar/panels/plugins/Plugin.kt b/library/Panels/src/main/java/com/bylazar/panels/plugins/Plugin.kt
index 5d81e405..b0a19d75 100644
--- a/library/Panels/src/main/java/com/bylazar/panels/plugins/Plugin.kt
+++ b/library/Panels/src/main/java/com/bylazar/panels/plugins/Plugin.kt
@@ -36,11 +36,15 @@ abstract class Plugin(baseConfig: T) {
}
fun log(message: String) {
- Logger.log("${Logger.PLUGINS_PREFIX}/${id}", message)
+ Logger.log("${Logger.PLUGINS_PREFIX}/${id.ifBlank { "UNKNOWN" }}", message)
}
fun error(message: String) {
- Logger.error("${Logger.PLUGINS_PREFIX}/${id}", message)
+ Logger.error("${Logger.PLUGINS_PREFIX}/${id.ifBlank { "UNKNOWN" }}", message)
+ }
+
+ fun error(message: String, e: Throwable) {
+ Logger.error("${Logger.PLUGINS_PREFIX}/${id.ifBlank { "UNKNOWN" }}", message, e)
}
fun send(type: String, data: Any) {
diff --git a/library/Panels/src/main/java/com/bylazar/panels/server/StaticServer.kt b/library/Panels/src/main/java/com/bylazar/panels/server/StaticServer.kt
index 657544fb..e4737470 100644
--- a/library/Panels/src/main/java/com/bylazar/panels/server/StaticServer.kt
+++ b/library/Panels/src/main/java/com/bylazar/panels/server/StaticServer.kt
@@ -25,6 +25,7 @@ class StaticServer(
init {
var files = listWebFiles(baseFolder)
+ Logger.serverLog("Found ${files.size} web files")
files.forEach {
Logger.serverLog("Found file: $it")
}
@@ -280,15 +281,15 @@ class StaticServer(
Logger.serverLog("Success")
return newChunkedResponse(Response.Status.OK, mime, inputStream).allowCors()
} catch (e: Exception) {
- Logger.serverLog("Primary asset not found: $path — ${e.message}")
+ Logger.serverError("Primary asset not found: $path", e)
return try {
val fallbackStream = assets.open("$baseFolder/index.html")
Logger.serverLog("Fallback to index.html")
newChunkedResponse(Response.Status.OK, "text/html", fallbackStream)
} catch (fallbackException: Exception) {
- val message = "Fallback also failed: ${fallbackException.message}"
- Logger.serverLog(message)
+ val message = "Fallback also failed, check logcat for more info"
+ Logger.serverError(message, fallbackException)
getResponse(message, status = Response.Status.INTERNAL_ERROR)
}
}
@@ -299,7 +300,7 @@ class StaticServer(
start()
Logger.serverLog("Server started on port $listeningPort")
} catch (e: IOException) {
- Logger.serverLog("Failed to start server: ${e.message}")
+ Logger.serverError("Failed to start server", e)
}
}
diff --git a/library/Panels/web/bun.lock b/library/Panels/web/bun.lock
index 21500d67..806acf29 100644
--- a/library/Panels/web/bun.lock
+++ b/library/Panels/web/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "panels-app",
diff --git a/library/Pinger/build.gradle.kts b/library/Pinger/build.gradle.kts
index 1b074238..b0e3d49a 100644
--- a/library/Pinger/build.gradle.kts
+++ b/library/Pinger/build.gradle.kts
@@ -2,56 +2,45 @@ val pluginNamespace = "com.bylazar.pinger"
val pluginVersion = "1.0.3"
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("maven-publish")
+ id("dev.frozenmilk.android-library") version "11.1.0-1.1.1"
id("com.bylazar.svelte-assets")
+ id("dev.frozenmilk.publish") version "0.0.5"
+ id("dev.frozenmilk.doc") version "0.0.5"
+ id("dev.frozenmilk.build-meta-data") version "0.0.2"
}
+android.namespace = pluginNamespace
+
svelteAssets {
- webAppPath = "web"
- buildDirPath = "dist"
- assetsPath = "web/plugins/$pluginNamespace"
+ assetsPath = assetPathForPlugin(pluginNamespace)
}
-android {
- namespace = pluginNamespace
-
- defaultConfig {
- compileSdk = 34
- minSdk = 24
- }
-
- buildTypes {
- getByName("release") {
- isMinifyEnabled = false
- }
- }
+dairyPublishing {
+ gitDir = file("..")
+}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- }
+version = "${dairyPublishing.version}+$pluginVersion"
- kotlinOptions {
- jvmTarget = "11"
- }
+meta {
+ packagePath = pluginNamespace
+ name = "Pinger"
+ registerField("name", "String", "\"$pluginNamespace\"")
+ registerField("clean", "Boolean") { "${dairyPublishing.clean}" }
+ registerField("gitRef", "String") { "\"${dairyPublishing.gitRef}\"" }
+ registerField("snapshot", "Boolean") { "${dairyPublishing.snapshot}" }
+ registerField("version", "String") { "\"$version\"" }
+}
- publishing {
- singleVariant("release") {}
+ftc {
+ kotlin()
+ sdk {
+ compileOnly(RobotCore)
+ compileOnly(FtcCommon)
+ compileOnly(RobotServer)
}
}
dependencies {
- compileOnly("org.firstinspires.ftc:Inspection:11.0.0")
- compileOnly("org.firstinspires.ftc:Blocks:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotCore:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotServer:11.0.0")
- compileOnly("org.firstinspires.ftc:OnBotJava:11.0.0")
- compileOnly("org.firstinspires.ftc:Hardware:11.0.0")
- compileOnly("org.firstinspires.ftc:FtcCommon:11.0.0")
- compileOnly("org.firstinspires.ftc:Vision:11.0.0")
-
compileOnly(project(":Panels"))
}
@@ -61,9 +50,11 @@ afterEvaluate {
create("release") {
from(components["release"])
- groupId = pluginNamespace.substringBeforeLast('.')
+ groupId = pluginNamespace.substringBeforeLast('.') + ".sloth"
artifactId = pluginNamespace.substringAfterLast('.')
- version = pluginVersion
+
+ artifact(dairyDoc.dokkaJavadocJar)
+ artifact(dairyDoc.dokkaHtmlJar)
pom {
description.set("Panels Pinger Plugin")
@@ -80,12 +71,5 @@ afterEvaluate {
}
}
}
-
- repositories {
- maven {
- name = "localDevRepo"
- url = uri("file:///C:/Users/lazar/Documents/GitHub/ftcontrol-maven/releases")
- }
- }
}
}
diff --git a/library/Pinger/src/main/java/com/bylazar/pinger/PingerPlugin.kt b/library/Pinger/src/main/java/com/bylazar/pinger/PingerPlugin.kt
index 274ead0b..159753df 100644
--- a/library/Pinger/src/main/java/com/bylazar/pinger/PingerPlugin.kt
+++ b/library/Pinger/src/main/java/com/bylazar/pinger/PingerPlugin.kt
@@ -9,7 +9,6 @@ import com.bylazar.panels.server.Socket
import com.qualcomm.ftccommon.FtcEventLoop
import com.qualcomm.robotcore.eventloop.opmode.OpMode
import com.qualcomm.robotcore.eventloop.opmode.OpModeManagerImpl
-import com.sun.tools.doclint.Entity.delta
open class ExamplePluginConfig : BasePluginConfig() {
}
diff --git a/library/Pinger/web/bun.lock b/library/Pinger/web/bun.lock
index b8db93ae..0d865e4a 100644
--- a/library/Pinger/web/bun.lock
+++ b/library/Pinger/web/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "panels-plugin",
diff --git a/library/TeamCode/build.gradle b/library/TeamCode/build.gradle
deleted file mode 100644
index 3e52c54d..00000000
--- a/library/TeamCode/build.gradle
+++ /dev/null
@@ -1,44 +0,0 @@
-//
-// build.gradle in TeamCode
-//
-// Most of the definitions for building your module reside in a common, shared
-// file 'build.common.gradle'. Being factored in this way makes it easier to
-// integrate updates to the FTC into your code. If you really need to customize
-// the build definitions, you can place those customizations in this file, but
-// please think carefully as to whether such customizations are really necessary
-// before doing so.
-
-
-// Custom definitions may go here
-
-// Include common definitions from above.
-apply from: '../build.common.gradle'
-apply from: '../build.dependencies.gradle'
-apply plugin: 'org.jetbrains.kotlin.android'
-
-android {
- namespace = 'org.firstinspires.ftc.teamcode'
-
- compileSdk 34
-
- packagingOptions {
- jniLibs.useLegacyPackaging true
- }
-
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_11
- targetCompatibility JavaVersion.VERSION_11
- }
- kotlinOptions {
- jvmTarget = '11'
- }
-}
-
-repositories {
-}
-
-dependencies {
- implementation project(':FtcRobotController')
- implementation project(':FullPanels')
- implementation project(':ExamplePlugin')
-}
diff --git a/library/TeamCode/build.gradle.kts b/library/TeamCode/build.gradle.kts
new file mode 100644
index 00000000..497754d3
--- /dev/null
+++ b/library/TeamCode/build.gradle.kts
@@ -0,0 +1,12 @@
+plugins {
+ id("dev.frozenmilk.teamcode") version "11.1.0-1.1.1"
+}
+
+ftc {
+ kotlin()
+ sdk.TeamCode()
+}
+
+dependencies {
+ implementation(project(":FullPanels"))
+}
\ No newline at end of file
diff --git a/library/TeamCode/lib/OpModeAnnotationProcessor.jar b/library/TeamCode/lib/OpModeAnnotationProcessor.jar
deleted file mode 100644
index 4825cc36..00000000
Binary files a/library/TeamCode/lib/OpModeAnnotationProcessor.jar and /dev/null differ
diff --git a/library/TeamCode/libs/ftc.debug.keystore b/library/TeamCode/libs/ftc.debug.keystore
new file mode 100644
index 00000000..a7204e66
Binary files /dev/null and b/library/TeamCode/libs/ftc.debug.keystore differ
diff --git a/library/Telemetry/build.gradle.kts b/library/Telemetry/build.gradle.kts
index 5470ad7b..48cae6a9 100644
--- a/library/Telemetry/build.gradle.kts
+++ b/library/Telemetry/build.gradle.kts
@@ -2,56 +2,45 @@ val pluginNamespace = "com.bylazar.telemetry"
val pluginVersion = "1.0.5"
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("maven-publish")
+ id("dev.frozenmilk.android-library") version "11.1.0-1.1.1"
id("com.bylazar.svelte-assets")
+ id("dev.frozenmilk.publish") version "0.0.5"
+ id("dev.frozenmilk.doc") version "0.0.5"
+ id("dev.frozenmilk.build-meta-data") version "0.0.2"
}
+android.namespace = pluginNamespace
+
svelteAssets {
- webAppPath = "web"
- buildDirPath = "dist"
- assetsPath = "web/plugins/$pluginNamespace"
+ assetsPath = assetPathForPlugin(pluginNamespace)
}
-android {
- namespace = pluginNamespace
-
- defaultConfig {
- compileSdk = 34
- minSdk = 24
- }
-
- buildTypes {
- getByName("release") {
- isMinifyEnabled = false
- }
- }
+dairyPublishing {
+ gitDir = file("..")
+}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- }
+version = "${dairyPublishing.version}+$pluginVersion"
- kotlinOptions {
- jvmTarget = "11"
- }
+meta {
+ packagePath = pluginNamespace
+ name = "Telemetry"
+ registerField("name", "String", "\"$pluginNamespace\"")
+ registerField("clean", "Boolean") { "${dairyPublishing.clean}" }
+ registerField("gitRef", "String") { "\"${dairyPublishing.gitRef}\"" }
+ registerField("snapshot", "Boolean") { "${dairyPublishing.snapshot}" }
+ registerField("version", "String") { "\"$version\"" }
+}
- publishing {
- singleVariant("release") {}
+ftc {
+ kotlin()
+ sdk {
+ compileOnly(RobotCore)
+ compileOnly(FtcCommon)
+ compileOnly(RobotServer)
}
}
dependencies {
- compileOnly("org.firstinspires.ftc:Inspection:11.0.0")
- compileOnly("org.firstinspires.ftc:Blocks:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotCore:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotServer:11.0.0")
- compileOnly("org.firstinspires.ftc:OnBotJava:11.0.0")
- compileOnly("org.firstinspires.ftc:Hardware:11.0.0")
- compileOnly("org.firstinspires.ftc:FtcCommon:11.0.0")
- compileOnly("org.firstinspires.ftc:Vision:11.0.0")
-
compileOnly(project(":Panels"))
}
@@ -61,9 +50,11 @@ afterEvaluate {
create("release") {
from(components["release"])
- groupId = pluginNamespace.substringBeforeLast('.')
+ groupId = pluginNamespace.substringBeforeLast('.') + ".sloth"
artifactId = pluginNamespace.substringAfterLast('.')
- version = pluginVersion
+
+ artifact(dairyDoc.dokkaJavadocJar)
+ artifact(dairyDoc.dokkaHtmlJar)
pom {
description.set("Panels Telemetry Plugin")
@@ -80,12 +71,5 @@ afterEvaluate {
}
}
}
-
- repositories {
- maven {
- name = "localDevRepo"
- url = uri("file:///C:/Users/lazar/Documents/GitHub/ftcontrol-maven/releases")
- }
- }
}
}
diff --git a/library/Telemetry/web/bun.lock b/library/Telemetry/web/bun.lock
index b8db93ae..0d865e4a 100644
--- a/library/Telemetry/web/bun.lock
+++ b/library/Telemetry/web/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "panels-plugin",
diff --git a/library/Themes/build.gradle.kts b/library/Themes/build.gradle.kts
index 686e4f2c..3f6e5273 100644
--- a/library/Themes/build.gradle.kts
+++ b/library/Themes/build.gradle.kts
@@ -2,56 +2,45 @@ val pluginNamespace = "com.bylazar.themes"
val pluginVersion = "1.0.3"
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("maven-publish")
+ id("dev.frozenmilk.android-library") version "11.1.0-1.1.1"
id("com.bylazar.svelte-assets")
+ id("dev.frozenmilk.publish") version "0.0.5"
+ id("dev.frozenmilk.doc") version "0.0.5"
+ id("dev.frozenmilk.build-meta-data") version "0.0.2"
}
+android.namespace = pluginNamespace
+
svelteAssets {
- webAppPath = "web"
- buildDirPath = "dist"
- assetsPath = "web/plugins/$pluginNamespace"
+ assetsPath = assetPathForPlugin(pluginNamespace)
}
-android {
- namespace = pluginNamespace
-
- defaultConfig {
- compileSdk = 34
- minSdk = 24
- }
-
- buildTypes {
- getByName("release") {
- isMinifyEnabled = false
- }
- }
+dairyPublishing {
+ gitDir = file("..")
+}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- }
+version = "${dairyPublishing.version}+$pluginVersion"
- kotlinOptions {
- jvmTarget = "11"
- }
+meta {
+ packagePath = pluginNamespace
+ name = "Themes"
+ registerField("name", "String", "\"$pluginNamespace\"")
+ registerField("clean", "Boolean") { "${dairyPublishing.clean}" }
+ registerField("gitRef", "String") { "\"${dairyPublishing.gitRef}\"" }
+ registerField("snapshot", "Boolean") { "${dairyPublishing.snapshot}" }
+ registerField("version", "String") { "\"$version\"" }
+}
- publishing {
- singleVariant("release") {}
+ftc {
+ kotlin()
+ sdk {
+ compileOnly(RobotCore)
+ compileOnly(FtcCommon)
+ compileOnly(RobotServer)
}
}
dependencies {
- compileOnly("org.firstinspires.ftc:Inspection:11.0.0")
- compileOnly("org.firstinspires.ftc:Blocks:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotCore:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotServer:11.0.0")
- compileOnly("org.firstinspires.ftc:OnBotJava:11.0.0")
- compileOnly("org.firstinspires.ftc:Hardware:11.0.0")
- compileOnly("org.firstinspires.ftc:FtcCommon:11.0.0")
- compileOnly("org.firstinspires.ftc:Vision:11.0.0")
-
compileOnly(project(":Panels"))
}
@@ -61,9 +50,11 @@ afterEvaluate {
create("release") {
from(components["release"])
- groupId = pluginNamespace.substringBeforeLast('.')
+ groupId = pluginNamespace.substringBeforeLast('.') + ".sloth"
artifactId = pluginNamespace.substringAfterLast('.')
- version = pluginVersion
+
+ artifact(dairyDoc.dokkaJavadocJar)
+ artifact(dairyDoc.dokkaHtmlJar)
pom {
description.set("Panels Themes Plugin")
@@ -80,12 +71,5 @@ afterEvaluate {
}
}
}
-
- repositories {
- maven {
- name = "localDevRepo"
- url = uri("file:///C:/Users/lazar/Documents/GitHub/ftcontrol-maven/releases")
- }
- }
}
}
diff --git a/library/Themes/web/bun.lock b/library/Themes/web/bun.lock
index 06220f3b..4386e178 100644
--- a/library/Themes/web/bun.lock
+++ b/library/Themes/web/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "panels-plugin",
diff --git a/library/Utils/build.gradle.kts b/library/Utils/build.gradle.kts
index b5768930..524206dd 100644
--- a/library/Utils/build.gradle.kts
+++ b/library/Utils/build.gradle.kts
@@ -2,58 +2,45 @@ val pluginNamespace = "com.bylazar.utils"
val pluginVersion = "1.0.4"
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("maven-publish")
+ id("dev.frozenmilk.android-library") version "11.1.0-1.1.1"
id("com.bylazar.svelte-assets")
+ id("dev.frozenmilk.publish") version "0.0.5"
+ id("dev.frozenmilk.doc") version "0.0.5"
+ id("dev.frozenmilk.build-meta-data") version "0.0.2"
}
+android.namespace = pluginNamespace
+
svelteAssets {
- webAppPath = "web"
- buildDirPath = "dist"
- assetsPath = "web/plugins/$pluginNamespace"
+ assetsPath = assetPathForPlugin(pluginNamespace)
}
-android {
- namespace = pluginNamespace
-
- defaultConfig {
- compileSdk = 34
- minSdk = 24
- }
-
- buildTypes {
- getByName("release") {
- isMinifyEnabled = false
- }
- }
+dairyPublishing {
+ gitDir = file("..")
+}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- }
+version = "${dairyPublishing.version}+$pluginVersion"
- kotlinOptions {
- jvmTarget = "11"
- }
+meta {
+ packagePath = pluginNamespace
+ name = "Utils"
+ registerField("name", "String", "\"$pluginNamespace\"")
+ registerField("clean", "Boolean") { "${dairyPublishing.clean}" }
+ registerField("gitRef", "String") { "\"${dairyPublishing.gitRef}\"" }
+ registerField("snapshot", "Boolean") { "${dairyPublishing.snapshot}" }
+ registerField("version", "String") { "\"$version\"" }
+}
- publishing {
- singleVariant("release") {
- withSourcesJar()
- }
+ftc {
+ kotlin()
+ sdk {
+ compileOnly(RobotCore)
+ compileOnly(FtcCommon)
+ compileOnly(RobotServer)
}
}
dependencies {
- compileOnly("org.firstinspires.ftc:Inspection:11.0.0")
- compileOnly("org.firstinspires.ftc:Blocks:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotCore:11.0.0")
- compileOnly("org.firstinspires.ftc:RobotServer:11.0.0")
- compileOnly("org.firstinspires.ftc:OnBotJava:11.0.0")
- compileOnly("org.firstinspires.ftc:Hardware:11.0.0")
- compileOnly("org.firstinspires.ftc:FtcCommon:11.0.0")
- compileOnly("org.firstinspires.ftc:Vision:11.0.0")
-
compileOnly(project(":Panels"))
}
@@ -63,9 +50,11 @@ afterEvaluate {
create("release") {
from(components["release"])
- groupId = pluginNamespace.substringBeforeLast('.')
+ groupId = pluginNamespace.substringBeforeLast('.') + ".sloth"
artifactId = pluginNamespace.substringAfterLast('.')
- version = pluginVersion
+
+ artifact(dairyDoc.dokkaJavadocJar)
+ artifact(dairyDoc.dokkaHtmlJar)
pom {
description.set("Panels Utils Plugin")
@@ -82,12 +71,5 @@ afterEvaluate {
}
}
}
-
- repositories {
- maven {
- name = "localDevRepo"
- url = uri("file:///C:/Users/lazar/Documents/GitHub/ftcontrol-maven/releases")
- }
- }
}
}
diff --git a/library/Utils/web/bun.lock b/library/Utils/web/bun.lock
index b8db93ae..0d865e4a 100644
--- a/library/Utils/web/bun.lock
+++ b/library/Utils/web/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "panels-plugin",
diff --git a/library/build.gradle.kts b/library/build.gradle.kts
index 44ecb6e2..232e7af1 100644
--- a/library/build.gradle.kts
+++ b/library/build.gradle.kts
@@ -1,33 +1,14 @@
-/**
- * Top-level build file for ftc_app project.
- *
- * It is extraordinarily rare that you will ever need to edit this file.
- */
-
-buildscript {
- val kotlin_version by extra("2.1.20")
-
- repositories {
- mavenCentral()
- google()
- }
-
- dependencies {
- // Note for FTC Teams: Do not modify this yourself.
- classpath("com.android.tools.build:gradle:8.7.0")
- classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
+fun makePublishAllTask(repository: String) = tasks.register("publishAllReleasePublicationsTo$repository") {
+ group = "Publishing"
+ description = "publish all release publications except ExamplePlugin to $repository"
+ subprojects.forEach { project ->
+ if (project.name == "ExamplePlugin") return@forEach
+ if (project.name == "TeamCode") return@forEach
+ if (project.name == "FtcRobotController") return@forEach
+ if (project.name == "plugin-svelte-assets") return@forEach
+ dependsOn(project.tasks.getByName("publishReleasePublicationTo$repository"))
}
}
-// This is now required because aapt2 has to be downloaded from the
-// google() repository beginning with version 3.2 of the Android Gradle Plugin
-allprojects {
- repositories {
- mavenCentral()
- google()
- }
-}
-
-repositories {
- mavenCentral()
-}
+makePublishAllTask("MavenLocal")
+makePublishAllTask("DairyRepository")
diff --git a/library/gradle.properties b/library/gradle.properties
index f5935e91..e392bd10 100644
--- a/library/gradle.properties
+++ b/library/gradle.properties
@@ -6,7 +6,10 @@ android.useAndroidX=true
# We no longer need to auto-convert third-party libraries to use AndroidX, which slowed down the build
android.enableJetifier=false
-# Allow Gradle to use up to 1 GB of RAM
-org.gradle.jvmargs=-Xmx1024M
+# Allow Gradle to use up to 2 GB of RAM
+org.gradle.jvmargs=-Xmx2048M
-android.nonTransitiveRClass=false
\ No newline at end of file
+android.nonTransitiveRClass=false
+
+org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled
+org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true
\ No newline at end of file
diff --git a/library/gradlew b/library/gradlew
old mode 100644
new mode 100755
diff --git a/library/plugin-svelte-assets/build.gradle.kts b/library/plugin-svelte-assets/build.gradle.kts
index 823e1a69..f375a4fa 100644
--- a/library/plugin-svelte-assets/build.gradle.kts
+++ b/library/plugin-svelte-assets/build.gradle.kts
@@ -12,6 +12,11 @@ repositories {
mavenCentral()
}
+dependencies {
+ //noinspection AndroidGradlePluginVersion
+ compileOnly("com.android.tools.build:gradle:8.7.0")
+}
+
gradlePlugin {
plugins {
create("svelteAssetsPlugin") {
diff --git a/library/plugin-svelte-assets/src/main/kotlin/com/bylazar/SvelteAssetsPlugin.kt b/library/plugin-svelte-assets/src/main/kotlin/com/bylazar/SvelteAssetsPlugin.kt
index 061417fa..e81f1dbb 100644
--- a/library/plugin-svelte-assets/src/main/kotlin/com/bylazar/SvelteAssetsPlugin.kt
+++ b/library/plugin-svelte-assets/src/main/kotlin/com/bylazar/SvelteAssetsPlugin.kt
@@ -1,251 +1,109 @@
package com.bylazar
+import com.android.build.api.variant.LibraryAndroidComponentsExtension
+import com.android.build.gradle.internal.tasks.factory.dependsOn
+import com.bylazar.tasks.BunTask
+import com.bylazar.tasks.InstallBunLocally
import org.gradle.api.Plugin
import org.gradle.api.Project
-import org.gradle.api.Task
-import org.gradle.api.GradleException
-import org.gradle.api.logging.LogLevel
import org.gradle.api.tasks.Copy
import org.gradle.api.tasks.Delete
-import org.gradle.api.tasks.Exec
-import org.gradle.api.services.BuildService
-import org.gradle.api.services.BuildServiceParameters
+import org.gradle.kotlin.dsl.register
import java.io.File
-import java.io.FileOutputStream
-import java.io.OutputStream
-import java.time.LocalDateTime
-import java.time.format.DateTimeFormatter
-
-open class SvelteAssetsPluginExtension {
- var webAppPath: String = "web"
- var buildDirPath: String = "build"
- var assetsPath: String = "web"
- var useNpm: Boolean = false
- var maxParallelSvelteBuilds: Int = 2
-}
-
-abstract class SvelteSingleSlotService :
- BuildService, AutoCloseable {
- override fun close() {}
-}
-
-class TeeOutputStream(
- private val a: OutputStream,
- private val b: OutputStream
-) : OutputStream() {
- override fun write(bte: Int) {
- a.write(bte); b.write(bte)
- }
- override fun write(btes: ByteArray) {
- a.write(btes); b.write(btes)
- }
- override fun write(btes: ByteArray, off: Int, len: Int) {
- a.write(btes, off, len); b.write(btes, off, len)
- }
- override fun flush() { a.flush(); b.flush() }
- override fun close() { a.close(); b.close() }
-}
-
-private object StdOutStream : OutputStream() {
- override fun write(b: Int) = System.out.write(b)
- override fun write(b: ByteArray, off: Int, len: Int) = System.out.write(b, off, len)
-}
-
-private object StdErrStream : OutputStream() {
- override fun write(b: Int) = System.err.write(b)
- override fun write(b: ByteArray, off: Int, len: Int) = System.err.write(b, off, len)
-}
+@Suppress("LocalVariableName", "unused")
class SvelteAssetsPlugin : Plugin {
override fun apply(project: Project) {
- val extension = project.extensions.create("svelteAssets", SvelteAssetsPluginExtension::class.java)
+ val extension =
+ project.extensions.create("svelteAssets", SvelteAssetsPluginExtension::class.java)
- project.plugins.withId("com.android.library") {
- configureAfterEvaluate(project, extension)
- }
- project.plugins.withId("com.android.application") {
- configureAfterEvaluate(project, extension)
- }
+ val BUN_INSTALL = project.rootProject.file(".bun")
- project.afterEvaluate {
- if (!project.plugins.hasPlugin("com.android.library")
- && !project.plugins.hasPlugin("com.android.application")
- ) {
- configure(project, extension)
- }
- }
- }
+ val generatedAssetsDir = File(
+ project.layout.buildDirectory.get().asFile,
+ "/generated/sources/frontend/assets",
+ )
- private fun configureAfterEvaluate(project: Project, extension: SvelteAssetsPluginExtension) {
- project.afterEvaluate { configure(project, extension) }
- }
+ val installBunLocally = project.tasks.register("installBunLocally")
- private fun configure(project: Project, extension: SvelteAssetsPluginExtension) {
- val isWindows = System.getProperty("os.name").lowercase().contains("windows")
- val webDir = File(project.projectDir, extension.webAppPath)
- val outputDir = File(project.projectDir, "src/main/assets/${extension.assetsPath}")
+ project.tasks.register("uninstallBun", Delete::class.java) {
+ group = "frontend"
+ description = "Removes the project's local bun installation."
+ delete(BUN_INSTALL)
+ }
+
+ val clearFrontendAssets =
+ project.tasks.register("clearFrontendAssets", Delete::class.java) {
+ group = "frontend"
+ description = "Clears frontend assets."
- val singleSlot = project.gradle.sharedServices
- .registerIfAbsent("svelteSingleSlot", SvelteSingleSlotService::class.java) {
- maxParallelUsages.set(extension.maxParallelSvelteBuilds.coerceAtLeast(1))
+ delete(generatedAssetsDir)
}
- val projectSuffix = project.name.replace(Regex("\\W+"), "")
- .replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }
+ val bunBuild = project.tasks.register("bunBuild") {
+ val webDir = project.file(extension.webAppPath)
- val installCmd = when {
- extension.useNpm && isWindows -> listOf("cmd", "/c", "npm", "i")
- extension.useNpm -> listOf("sh", "-c", "npm i")
- !extension.useNpm && isWindows -> listOf("cmd", "/c", "bun", "i")
- else -> listOf("sh", "-c", "bun i")
- }
- val buildCmd = when {
- extension.useNpm && isWindows -> listOf("cmd", "/c", "npm", "run", "build")
- extension.useNpm -> listOf("sh", "-c", "npm run build")
- !extension.useNpm && isWindows -> listOf("cmd", "/c", "bun", "run", "build")
- else -> listOf("sh", "-c", "bun run build")
- }
+ group = "frontend"
+ description = "Installs frontend dependencies, then builds the frontend."
- val clearSvelte = project.tasks.register("clearSvelteAssets$projectSuffix", Delete::class.java) {
- group = "svelte"
- description = "Clears web assets for ${project.path}"
- val pluginsDir1 = File(project.projectDir, "src/main/assets/plugins")
- if (pluginsDir1.exists()) delete(pluginsDir1.listFiles()?.toList() ?: emptyList())
- val pluginsDir2 = File(project.projectDir, "src/main/assets/${extension.assetsPath}")
- if (pluginsDir2.exists()) delete(pluginsDir2.listFiles()?.toList() ?: emptyList())
- }
+ dependsOn(installBunLocally)
- val installSvelteApp = project.tasks.register("installSvelteApp$projectSuffix", Exec::class.java) {
- group = "svelte"
- description = "Installs web dependencies for ${project.path} (${if (extension.useNpm) "npm" else "bun"})"
- dependsOn(clearSvelte)
- workingDir = webDir
- commandLine = installCmd
- isIgnoreExitValue = true
- usesService(singleSlot)
- }
- attachExecLogging(project, installSvelteApp, "install")
-
- val buildSvelteApp = project.tasks.register("buildSvelteApp$projectSuffix", Exec::class.java) {
- group = "svelte"
- description = "Builds the Svelte app for ${project.path}"
- dependsOn(installSvelteApp)
- workingDir = webDir
- commandLine = buildCmd
- isIgnoreExitValue = true
- usesService(singleSlot)
- }
- attachExecLogging(project, buildSvelteApp, "build")
-
- val copySvelteToAssets = project.tasks.register("copySvelteToAssets$projectSuffix", Copy::class.java) {
- group = "svelte"
- description = "Copies the built Svelte assets into ${outputDir.relativeTo(project.projectDir)} for ${project.path}"
- dependsOn(buildSvelteApp)
- from(File(webDir, extension.buildDirPath))
- into(outputDir)
- }
+ val inputFiles = project.fileTree(webDir) {
+ exclude(extension.buildDirPath)
+ exclude("node_modules")
+ exclude(".panels")
+ exclude(".svelte-kit")
+ }
- val buildSvelteAggregate = project.tasks.register("buildSvelte$projectSuffix") {
- group = "svelte"
- description = "Installs, builds, and copies Svelte assets for ${project.path}"
- dependsOn(copySvelteToAssets)
- usesService(singleSlot)
- }
+ inputs.dir(inputFiles)
- val root = project.rootProject
- val rootTask = root.tasks.findByName("buildAllSvelte")
- ?: root.tasks.create("buildAllSvelte") {
- group = "svelte"
- description = "Builds Svelte assets for all subprojects"
- }
- rootTask.dependsOn(buildSvelteAggregate)
-
- val extra = root.extensions.extraProperties
- val keyAggregates = "svelteAggregates"
- val keyWired = "svelteAggregatesWired"
-
- @Suppress("UNCHECKED_CAST")
- val aggregates: MutableList> =
- if (extra.has(keyAggregates)) {
- extra.get(keyAggregates) as MutableList>
- } else {
- mutableListOf>().also {
- extra.set(keyAggregates, it)
- }
- }
- aggregates.add(buildSvelteAggregate)
-
- if (!extra.has(keyWired)) {
- extra.set(keyWired, true)
- root.gradle.projectsEvaluated {
- @Suppress("UNCHECKED_CAST")
- val allProviders = (extra.get(keyAggregates)
- as MutableList>).toList()
- if (allProviders.isNotEmpty()) {
- val allTasks = allProviders.map { it.get() }.sortedWith(
- compareBy { it.project.path }.thenBy { it.name }
- )
- for (i in 1 until allTasks.size) {
- allTasks[i].dependsOn(allTasks[i - 1])
- }
- rootTask.setDependsOn(listOf(allTasks.last()))
- }
- root.tasks.matching { it.name == "publish" }.configureEach {
- dependsOn(rootTask)
+ outputs.dir(File(webDir, extension.buildDirPath))
+ outputs.dir(File(webDir, "node_modules"))
+ outputs.dir(File(webDir, ".panels"))
+ outputs.dir(File(webDir, ".svelte-kit"))
+
+ doLast {
+ bunExec("bun i && bun run build") {
+ workingDir = webDir
}
}
}
- }
- private fun attachExecLogging(
- project: Project,
- taskProvider: org.gradle.api.tasks.TaskProvider,
- label: String
- ) {
- taskProvider.configure {
- val relProjectPath = project.path.removePrefix(":").ifEmpty { "root" }
- val safePath = relProjectPath.replace(':', '_')
- val logsDir = File(project.buildDir, "svelte-logs/$safePath").also { it.mkdirs() }
-
- val timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss"))
- val latestLog = File(logsDir, "$label.log")
- val tsLog = File(logsDir, "$label-$timestamp.log")
-
- doFirst {
- logsDir.mkdirs()
- project.logger.log(
- LogLevel.LIFECYCLE,
- "[svelte] ${project.path} ${name}: logging to ${latestLog.relativeTo(project.projectDir)} (and ${tsLog.name})"
+ val copyFrontendToAssets =
+ project.tasks.register("copyFrontendToAssets", Copy::class.java) {
+ val assetsPath = requireNotNull(extension.assetsPath) { "assets path must be set" }
+ val outputDir = File(
+ generatedAssetsDir,
+ assetsPath,
)
- val fout = FileOutputStream(latestLog, false)
- val fts = FileOutputStream(tsLog, false)
- val fileTee = TeeOutputStream(fout, fts)
- val stdoutTee = TeeOutputStream(StdOutStream, fileTee)
- val stderrTee = TeeOutputStream(StdErrStream, fileTee)
- standardOutput = stdoutTee
- errorOutput = stderrTee
- val header = "===== ${project.path} :: $name ($label) :: $timestamp =====\n"
- stdoutTee.write(header.toByteArray())
- stdoutTee.flush()
+ val webDir = project.file(extension.webAppPath)
+
+ group = "frontend"
+ description =
+ "Copies the built frontend assets into ${outputDir.relativeTo(project.projectDir)}."
+
+ dependsOn(clearFrontendAssets)
+ dependsOn(bunBuild)
+
+ from(File(webDir, extension.buildDirPath))
+ into(outputDir)
}
- doLast {
- val result = executionResult.get()
- val exit = result.exitValue
- if (exit != 0) {
- val tailLines = 200
- val lines = if (latestLog.exists()) latestLog.readLines() else emptyList()
- val tail = lines.takeLast(tailLines)
- project.logger.error(
- "\n\u001B[31m[svelte] ${project.path} ${name} failed (exit $exit). " +
- "Showing last $tailLines log lines from ${latestLog.relativeTo(project.projectDir)}:\u001B[0m"
- )
- tail.forEach { project.logger.error(it) }
- throw GradleException(
- "[svelte] ${project.path} ${name} failed. Full log: ${latestLog.absolutePath}"
- )
- }
+ val buildFrontend = project.tasks.register("buildFrontend") {
+ group = "frontend"
+ description = "Builds frontend assets for bundling into the library."
+
+ dependsOn(copyFrontendToAssets)
+
+ outputs.dir(generatedAssetsDir)
+ }
+
+ project.extensions.getByType(LibraryAndroidComponentsExtension::class.java).finalizeDsl {
+ it.sourceSets.getByName("main") {
+ assets.srcDir(generatedAssetsDir)
}
}
+
+ project.tasks.named("preBuild").dependsOn(buildFrontend)
}
}
diff --git a/library/plugin-svelte-assets/src/main/kotlin/com/bylazar/SvelteAssetsPluginExtension.kt b/library/plugin-svelte-assets/src/main/kotlin/com/bylazar/SvelteAssetsPluginExtension.kt
new file mode 100644
index 00000000..4a0fa875
--- /dev/null
+++ b/library/plugin-svelte-assets/src/main/kotlin/com/bylazar/SvelteAssetsPluginExtension.kt
@@ -0,0 +1,8 @@
+package com.bylazar
+
+abstract class SvelteAssetsPluginExtension {
+ fun assetPathForPlugin(pluginNamespace: String) = "web/plugins/$pluginNamespace"
+ var assetsPath: String? = null
+ var webAppPath: String = "web"
+ var buildDirPath: String = "dist"
+}
\ No newline at end of file
diff --git a/library/plugin-svelte-assets/src/main/kotlin/com/bylazar/tasks/BunTask.kt b/library/plugin-svelte-assets/src/main/kotlin/com/bylazar/tasks/BunTask.kt
new file mode 100644
index 00000000..9ad4c61e
--- /dev/null
+++ b/library/plugin-svelte-assets/src/main/kotlin/com/bylazar/tasks/BunTask.kt
@@ -0,0 +1,46 @@
+package com.bylazar.tasks
+
+import org.gradle.api.DefaultTask
+import org.gradle.api.tasks.CacheableTask
+import org.gradle.api.tasks.Internal
+import org.gradle.process.ExecSpec
+import java.io.File
+
+@CacheableTask
+abstract class BunTask : DefaultTask() {
+ companion object {
+ val isWindows = System.getProperty("os.name").lowercase().contains("windows")
+ }
+
+ @Suppress("PropertyName")
+ @get:Internal
+ val BUN_INSTALL = project.rootProject.file(".bun")
+
+ @get:Internal
+ val bunInstalledLocally
+ get() = (isWindows && File(BUN_INSTALL, "bin\\bun.exe").exists())//
+ || (!isWindows && File(BUN_INSTALL, "bin/bun").exists())
+
+ @get:Internal
+ val bunInstalled
+ get() = System.getenv("BUN_INSTALL") != null || bunInstalledLocally
+
+ /**
+ * executes [cmd] under powershell or sh,
+ * with the appropriate env vars set to use the locally installed bun
+ * if necessary
+ */
+ fun bunExec(cmd: String, action: ExecSpec.() -> Unit = {}) {
+ project.exec {
+ commandLine = if (isWindows) listOf("powershell", "-c", cmd)
+ else listOf("sh", "-c", cmd)
+ if (bunInstalledLocally) {
+ environment["BUN_INSTALL"] = BUN_INSTALL.absolutePath
+ environment["PATH"] =
+ if (isWindows) "${BUN_INSTALL.absolutePath}\\bin;${System.getenv("PATH")}"
+ else "${BUN_INSTALL.absolutePath}/bin:${System.getenv("PATH")}"
+ }
+ action()
+ }
+ }
+}
\ No newline at end of file
diff --git a/library/plugin-svelte-assets/src/main/kotlin/com/bylazar/tasks/InstallBunLocally.kt b/library/plugin-svelte-assets/src/main/kotlin/com/bylazar/tasks/InstallBunLocally.kt
new file mode 100644
index 00000000..29ddb79e
--- /dev/null
+++ b/library/plugin-svelte-assets/src/main/kotlin/com/bylazar/tasks/InstallBunLocally.kt
@@ -0,0 +1,21 @@
+package com.bylazar.tasks
+
+import org.gradle.api.tasks.TaskAction
+
+abstract class InstallBunLocally : BunTask() {
+ init {
+ group = "frontend"
+ onlyIf { !bunInstalled }
+ }
+
+ @TaskAction
+ fun installBun() {
+ project.exec {
+ commandLine = if (isWindows) listOf("powershell", "-c", "irm bun.sh/install.ps1|iex")
+ else listOf("sh", "-c", "curl -fsSL https://bun.com/install | bash\n")
+ environment["BUN_INSTALL"] = BUN_INSTALL.absolutePath
+ standardOutput = System.out
+ errorOutput = System.err
+ }
+ }
+}
\ No newline at end of file
diff --git a/library/settings.gradle.kts b/library/settings.gradle.kts
index 420e1e84..7351a904 100644
--- a/library/settings.gradle.kts
+++ b/library/settings.gradle.kts
@@ -2,10 +2,12 @@ pluginManagement {
includeBuild("plugin-svelte-assets")
repositories {
gradlePluginPortal()
+ google()
+ mavenCentral()
+ maven("https://repo.dairy.foundation/releases")
}
}
-include(":FtcRobotController")
include(":TeamCode")
include(":OpModeControl")
include(":ExamplePlugin")
@@ -23,4 +25,5 @@ include(":Panels")
include(":Utils")
include(":Pinger")
include(":Graph")
-include(":Lights")
\ No newline at end of file
+include(":Lights")
+include(":CameraStream")
\ No newline at end of file