diff --git a/FtcRobotController/src/main/AndroidManifest.xml b/FtcRobotController/src/main/AndroidManifest.xml index 4c5857680eb2..143c1f1ba0f9 100644 --- a/FtcRobotController/src/main/AndroidManifest.xml +++ b/FtcRobotController/src/main/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="62" + android:versionName="11.2"> diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/BasicOpMode_Linear.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/BasicOpMode_Linear.java index ab0bb254c1d9..18979922edbb 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/BasicOpMode_Linear.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/BasicOpMode_Linear.java @@ -38,7 +38,7 @@ /* - * This file contains an minimal example of a Linear "OpMode". An OpMode is a 'program' that runs in either + * This file contains a 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. diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTag.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTag.java index 4ee7ffefc84e..44abd97984c7 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTag.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTag.java @@ -34,7 +34,9 @@ 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.CameraCompatibilityManager; import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName; +import org.firstinspires.ftc.robotcore.internal.usb.UsbConstants; import org.firstinspires.ftc.vision.VisionPortal; import org.firstinspires.ftc.vision.apriltag.AprilTagDetection; import org.firstinspires.ftc.vision.apriltag.AprilTagProcessor; @@ -81,9 +83,33 @@ public class ConceptAprilTag extends LinearOpMode { */ private VisionPortal visionPortal; + // To find the VID/PID for a camera: + // + // Linux: open a terminal, run "lsusb", locate the line for your camera, + // and find the section that resembles "ID 1d6b:0002"; this is VID:PID + // + // OSX: open a terminal, run "system_profiler SPUSBDataType", locate the + // section for your camera, and find the "Product ID:" and "Vendor ID:" + // listings in the output + // + // Windows: open a PowerShell, run: + // Get-PnpDevice -PresentOnly | Where-Object { $_.InstanceId -like 'USB*' } | Select-Object FriendlyName, InstanceId + // and locate the line for your camera. The VID and PID is listed directly in the line. + static final int VENDOR_ID_SUNPLUS_INNOVATION_TECHNOLOGY = 0x1BCF; + static final int PRODUCT_ID_ARDUCAM_OV5648 = 0x284C; + @Override public void runOpMode() { + // Demonstrate how to add a camera compatibility quirk + // these can sometimes be needed if a camera behaves poorly. + // Quirks have no effect unless the camera you are using matches the specified VID/PID + CameraCompatibilityManager.getInstance() + .addQuirk( + VENDOR_ID_SUNPLUS_INNOVATION_TECHNOLOGY, + PRODUCT_ID_ARDUCAM_OV5648, + CameraCompatibilityManager.Quirk.AVOID_LIB_USB_RESET_DEVICE); + initAprilTag(); // Wait for the DS start button to be touched. diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagEasy.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagEasy.java index 7bda71b40f86..76ace3c5bfca 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagEasy.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagEasy.java @@ -33,6 +33,7 @@ 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.CameraCompatibilityManager; import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName; import org.firstinspires.ftc.vision.VisionPortal; import org.firstinspires.ftc.vision.apriltag.AprilTagDetection; @@ -77,9 +78,33 @@ public class ConceptAprilTagEasy extends LinearOpMode { */ private VisionPortal visionPortal; + // To find the VID/PID for a camera: + // + // Linux: open a terminal, run "lsusb", locate the line for your camera, + // and find the section that resembles "ID 1d6b:0002"; this is VID:PID + // + // OSX: open a terminal, run "system_profiler SPUSBDataType", locate the + // section for your camera, and find the "Product ID:" and "Vendor ID:" + // listings in the output + // + // Windows: open a PowerShell, run: + // Get-PnpDevice -PresentOnly | Where-Object { $_.InstanceId -like 'USB*' } | Select-Object FriendlyName, InstanceId + // and locate the line for your camera. The VID and PID is listed directly in the line. + static final int VENDOR_ID_SUNPLUS_INNOVATION_TECHNOLOGY = 0x1BCF; + static final int PRODUCT_ID_ARDUCAM_OV5648 = 0x284C; + @Override public void runOpMode() { + // Demonstrate how to add a camera compatibility quirk + // these can sometimes be needed if a camera behaves poorly. + // Quirks have no effect unless the camera you are using matches the specified VID/PID + CameraCompatibilityManager.getInstance() + .addQuirk( + VENDOR_ID_SUNPLUS_INNOVATION_TECHNOLOGY, + PRODUCT_ID_ARDUCAM_OV5648, + CameraCompatibilityManager.Quirk.AVOID_LIB_USB_RESET_DEVICE); + initAprilTag(); // Wait for the DS start button to be touched. diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagLocalization.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagLocalization.java index 3cb4d9fb0f58..a14b971cbc91 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagLocalization.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptAprilTagLocalization.java @@ -34,6 +34,7 @@ import com.qualcomm.robotcore.eventloop.opmode.TeleOp; import org.firstinspires.ftc.robotcore.external.hardware.camera.BuiltinCameraDirection; +import org.firstinspires.ftc.robotcore.external.hardware.camera.CameraCompatibilityManager; 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; @@ -109,9 +110,33 @@ public class ConceptAprilTagLocalization extends LinearOpMode { */ private VisionPortal visionPortal; + // To find the VID/PID for a camera: + // + // Linux: open a terminal, run "lsusb", locate the line for your camera, + // and find the section that resembles "ID 1d6b:0002"; this is VID:PID + // + // OSX: open a terminal, run "system_profiler SPUSBDataType", locate the + // section for your camera, and find the "Product ID:" and "Vendor ID:" + // listings in the output + // + // Windows: open a PowerShell, run: + // Get-PnpDevice -PresentOnly | Where-Object { $_.InstanceId -like 'USB*' } | Select-Object FriendlyName, InstanceId + // and locate the line for your camera. The VID and PID is listed directly in the line. + static final int VENDOR_ID_SUNPLUS_INNOVATION_TECHNOLOGY = 0x1BCF; + static final int PRODUCT_ID_ARDUCAM_OV5648 = 0x284C; + @Override public void runOpMode() { + // Demonstrate how to add a camera compatibility quirk + // these can sometimes be needed if a camera behaves poorly. + // Quirks have no effect unless the camera you are using matches the specified VID/PID + CameraCompatibilityManager.getInstance() + .addQuirk( + VENDOR_ID_SUNPLUS_INNOVATION_TECHNOLOGY, + PRODUCT_ID_ARDUCAM_OV5648, + CameraCompatibilityManager.Quirk.AVOID_LIB_USB_RESET_DEVICE); + initAprilTag(); // Wait for the DS start button to be touched. diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/utilities/UtilityTestGamepad.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/utilities/UtilityTestGamepad.java new file mode 100644 index 000000000000..a27230083f1a --- /dev/null +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/utilities/UtilityTestGamepad.java @@ -0,0 +1,137 @@ +package org.firstinspires.ftc.robotcontroller.external.utilities; +/* + Copyright (c) 2026 Porpoiseful, LLC + 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 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. +*/ + +import com.qualcomm.robotcore.eventloop.opmode.OpMode; +import com.qualcomm.robotcore.eventloop.opmode.Utility; +import com.qualcomm.robotcore.hardware.Gamepad; + +/* + * This OpMode helps test the gamepads so you can make sure they are functional. + * + */ +@Utility(name = "Test Gamepad", description = "Test gamepads on your driver station") +@SuppressWarnings("unused") +public class UtilityTestGamepad extends OpMode { + + public static final String SEPARATOR = " • "; + + @Override + public void init(){ + telemetry.addData("Instructions", "Setup your gamepads and then press the play button"); + } + + @Override + public void loop() { + display_gamepad(gamepad1, "Gamepad 1"); + display_gamepad(gamepad2, "Gamepad 2"); + } + + void display_gamepad(Gamepad gamepad, String name) { + telemetry.addLine("---" + name + "---"); + telemetry.addData("Left Joystick", "(% 1.2f, %1.2f)", gamepad.left_stick_x, gamepad.left_stick_y); + telemetry.addData("Left Trigger", "% 1.2f", gamepad.left_trigger); + telemetry.addData("Right Joystick", "(% 1.2f, %1.2f)", gamepad.right_stick_x, gamepad.right_stick_y); + telemetry.addData("Right Trigger", "% 1.2f", gamepad.right_trigger); + + switch(gamepad.type()){ + case SONY_PS4: + case SONY_PS4_SUPPORTED_BY_KERNEL: + + if (gamepad.touchpad_finger_1) { + telemetry.addData("Touchpad Finger1", "(% 1.2f, %1.2f)", gamepad.touchpad_finger_1_x, gamepad.touchpad_finger_1_y); + } else { + telemetry.addData("Touchpad Finger1", false); + } + + if (gamepad.touchpad_finger_2) { + telemetry.addData("Touchpad Finger2", "(% 1.2f, %1.2f)", gamepad.touchpad_finger_2_x, gamepad.touchpad_finger_2_y); + } else { + telemetry.addData("Touchpad Finger2", false); + } + + telemetry.addData("Buttons", ps_buttons_to_string(gamepad)); + break; + case LOGITECH_F310: + case XBOX_360: + case UNKNOWN: + default: + telemetry.addData("Buttons", xbox_buttons_to_string(gamepad)); + break; + } + } + + /* + This returns a string based off of the buttons pressed, with the xbox names for buttons + */ + String xbox_buttons_to_string(Gamepad gamepad){ + String buttons = generic_buttons_to_string(gamepad); + if (gamepad.back) buttons += "back" + SEPARATOR; + if (gamepad.start) buttons += "start" + SEPARATOR; + if (gamepad.guide) buttons += "guide" + SEPARATOR; + if (gamepad.a) buttons += "a" + SEPARATOR; + if (gamepad.b) buttons += "b" + SEPARATOR; + if (gamepad.x) buttons += "x" + SEPARATOR; + if (gamepad.y) buttons += "y" + SEPARATOR; + + return buttons; + } + + /* + This returns a string based off of the buttons pressed, with the ps names for buttons + */ + String ps_buttons_to_string(Gamepad gamepad){ + String buttons = generic_buttons_to_string(gamepad); + if (gamepad.cross) buttons += "cross" + SEPARATOR; + if (gamepad.circle) buttons += "circle" + SEPARATOR; + if (gamepad.square) buttons += "square" + SEPARATOR; + if (gamepad.triangle) buttons += "triangle" + SEPARATOR; + if (gamepad.ps) buttons += "ps" + SEPARATOR; + if (gamepad.share) buttons += "share" + SEPARATOR; + if (gamepad.options) buttons += "options" + SEPARATOR; + if (gamepad.touchpad) buttons += "touchpad" + SEPARATOR; + + return buttons; + } + + /* + This returns the buttons pressed for those that are the same on both types of gamepads + */ + String generic_buttons_to_string(Gamepad gamepad){ + String buttons = ""; + if (gamepad.dpad_up) buttons += "dpad_up" + SEPARATOR; + if (gamepad.dpad_down) buttons += "dpad_down" + SEPARATOR; + if (gamepad.dpad_left) buttons += "dpad_left" + SEPARATOR; + if (gamepad.dpad_right) buttons += "dpad_right" + SEPARATOR; + if (gamepad.left_bumper) buttons += "left_bumper" + SEPARATOR; + if (gamepad.right_bumper) buttons += "right_bumper" + SEPARATOR; + if (gamepad.left_stick_button) buttons += "left stick button" + SEPARATOR; + if (gamepad.right_stick_button) buttons += "right stick button" + SEPARATOR; + return buttons; + } + +} diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/utilities/UtilityTestHardware.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/utilities/UtilityTestHardware.java new file mode 100644 index 000000000000..9e48dfec83ba --- /dev/null +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/utilities/UtilityTestHardware.java @@ -0,0 +1,204 @@ +package org.firstinspires.ftc.robotcontroller.external.utilities; +/* + Copyright (c) 2026 Porpoiseful, LLC + 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 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. +*/ + +import com.qualcomm.robotcore.eventloop.opmode.OpMode; +import com.qualcomm.robotcore.eventloop.opmode.Utility; +import com.qualcomm.robotcore.hardware.AnalogSensor; +import com.qualcomm.robotcore.hardware.CRServo; +import com.qualcomm.robotcore.hardware.ColorSensor; +import com.qualcomm.robotcore.hardware.DcMotor; +import com.qualcomm.robotcore.hardware.DigitalChannel; +import com.qualcomm.robotcore.hardware.DistanceSensor; +import com.qualcomm.robotcore.hardware.HardwareDevice; +import com.qualcomm.robotcore.hardware.IMU; +import com.qualcomm.robotcore.hardware.Servo; +import com.qualcomm.robotcore.hardware.TouchSensor; + +import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName; +import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/* + * This OpMode helps test the hardware in your robot configuration so that you can isolate + * wiring and mechanical problems from software ones. + * + * WARNING: This only allows activations of a single actuator at a time so if you have two tied + * together, you need to make sure that can't cause damage to your robot. + */ +@Utility(name = "Test Hardware", description = "Test hardware devices in your robot configuration") +@SuppressWarnings("unused") +public class UtilityTestHardware extends OpMode { + protected static class Device { + String configName; + HardwareDevice hardwareDevice; + + Device(String name, HardwareDevice device) { + this.configName = name; + this.hardwareDevice = device; + } + } + + int numDevice = 0; + List deviceList = new ArrayList<>(); + + @Override + public void init() { + for (HardwareDevice device : hardwareMap) { + Set stringSet = hardwareMap.getNamesOf(device); + for (String name : stringSet) { + if (!(name.startsWith("Control Hub") || name.startsWith("Expansion Hub"))) { + deviceList.add(new Device(name, device)); + } + } + } + telemetry.addData("Num Configurations", deviceList.size()); + } + + @Override + public void loop() { + if (deviceList.isEmpty()){ + telemetry.addData("No Devices", "Found"); + return; + } + telemetry.addData("Use Dpad Left/Right", "to select device"); + if (gamepad1.dpadRightWasPressed()) { + numDevice++; + if (numDevice >= deviceList.size()) { + numDevice = 0; + } + } else if (gamepad1.dpadLeftWasPressed()) { + numDevice--; + if (numDevice < 0) { + numDevice = deviceList.size() - 1; + } + } + try { + telemetry.addData("Config Name", deviceList.get(numDevice).configName); + HardwareDevice hardwareDevice = deviceList.get(numDevice).hardwareDevice; + telemetry.addData("Device Type", hardwareDevice.getDeviceName()); + telemetry.addData("Connection Info", hardwareDevice.getConnectionInfo()); + if (hardwareDevice instanceof DcMotor) { + testMotor((DcMotor) hardwareDevice); + } else if (hardwareDevice instanceof CRServo) { + testCRServo((CRServo) hardwareDevice); + } else if (hardwareDevice instanceof Servo) { + testServo((Servo) hardwareDevice); + } else if (hardwareDevice instanceof ColorSensor) { + testColorSensor((ColorSensor) hardwareDevice); + // could be both, so check in here + if (hardwareDevice instanceof DistanceSensor) { + testDistanceSensor((DistanceSensor) hardwareDevice); + } + } else if (hardwareDevice instanceof DistanceSensor) { + testDistanceSensor((DistanceSensor) hardwareDevice); + } else if (hardwareDevice instanceof TouchSensor) { + testTouchSensor((TouchSensor) hardwareDevice); + } else if (hardwareDevice instanceof IMU) { + testIMU((IMU) hardwareDevice); + } else if (hardwareDevice instanceof WebcamName) { + testWebcam((WebcamName) hardwareDevice); + } else if (hardwareDevice instanceof AnalogSensor) { + testAnalogSensor((AnalogSensor) hardwareDevice); + } else if (hardwareDevice instanceof DigitalChannel) { + testDigitalChannel((DigitalChannel) hardwareDevice); + } else { + telemetry.addData("Testing", "Not supported"); + } + } catch (Exception e) { + telemetry.addData("Exception", e.toString()); + } + } + + void testMotor(DcMotor motor) { + telemetry.addData("Use Left joystick Y", "to set motor power"); + telemetry.addData("Use Right Bumper", "to set motor power to value"); + double power = -gamepad1.left_stick_y; + telemetry.addData("Encoder", motor.getCurrentPosition()); + telemetry.addData("Value", power); + if (gamepad1.right_bumper) { + telemetry.addData("Motor power set to", power); + motor.setPower(power); + } + } + + void testServo(Servo servo) { + telemetry.addData("Use Left joystick Y", "to select value for servo position"); + telemetry.addData("Use Right Bumper", "to set servo position to value"); + double position = .5 + (-gamepad1.left_stick_y / 2); + telemetry.addData("Value", position); + if (gamepad1.right_bumper) { + telemetry.addData("Servo position set to", position); + servo.setPosition(position); + } + } + + void testCRServo(CRServo crServo) { + telemetry.addData("Use Left joystick Y", "to select value for CR servo speed"); + telemetry.addData("Use Right Bumper", "to set CR servo speed to value"); + double power = -gamepad1.left_stick_y; + telemetry.addData("Value", power); + if (gamepad1.right_bumper) { + telemetry.addData("CRServo speed set to", power); + crServo.setPower(power); + } + } + + void testColorSensor(ColorSensor colorSensor) { + telemetry.addData("Red", colorSensor.red()); + telemetry.addData("Green", colorSensor.green()); + telemetry.addData("Blue", colorSensor.blue()); + } + + void testDistanceSensor(DistanceSensor distanceSensor) { + telemetry.addData("Distance (IN)", distanceSensor.getDistance(DistanceUnit.INCH)); + telemetry.addData("Distance (CM)", distanceSensor.getDistance(DistanceUnit.CM)); + } + + void testTouchSensor(TouchSensor touchSensor) { + telemetry.addData("Pressed", touchSensor.isPressed()); + } + + void testIMU(IMU imu) { + telemetry.addData("Yaw Pitch Roll", imu.getRobotYawPitchRollAngles()); + } + + void testWebcam(WebcamName webcamName) { + telemetry.addData("isAttached", webcamName.isAttached()); + } + + void testAnalogSensor(AnalogSensor analogSensor) { + telemetry.addData("Voltage", analogSensor.readRawVoltage()); + } + void testDigitalChannel(DigitalChannel digitalChannel) { + telemetry.addData("State", digitalChannel.getState()); + } + +} diff --git a/README.md b/README.md index 355d349291f8..e1e43ec2663a 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,37 @@ The readme.md file located in the [/TeamCode/src/main/java/org/firstinspires/ftc # Release Information +## Version 11.2 (20260707-102819) + +### Breaking Changes +* Gradle is upgraded to v9.1 and the Android Gradle Plugin is updated to v8.13.2. AGP v8.13.2 requires Android Studio Narwhal 3 Feature Drop or later. Earlier versions of Android Studio will fail to sync the project. Older versions of Android Studio may prompt the user to downgrade AGP. Do not do this. Gradle v9.1 removed support for features that older versions of the AGP use. Updating Gradle fixes a Windows 11 problem some teams may encounter if they have agressive security software installed on their machine. For more context see [this Gradle issue](https://github.com/gradle/gradle/issues/31438) + +### Enhancements +* New type of OpMode is now available. (`@Utility`) + * Utility opmodes that are not disabled will show up in the Utility menu (requires 11.2 or later DS and RC) +* TestHardware Utility now available + * It allows you to test all servos, CR servos, motors, Color sensors, distance sensors, touch sensors, IMUs, webcams, and analog sensors in the config +* TestGamepad Utility now available + * It allows you to see the results of your two gamepads to make sure it is what you expect and find problems with your gamepads. +* Adds methods to PwmControl interface to allow you to setPulseWidth and getPulseWidth + * Both of these are in microseconds (uSeconds) + * This is an ADVANCED feature. There is not a supporting sample. + * NOTE: You may see a slight difference since the hardware is not accurate to the microsecond +* Adds ability to set UVC camera "quirks" from user code to control compatibility flags used inside the low level UVC driver. Addresses issue [1428](https://github.com/FIRST-Tech-Challenge/FtcRobotController/issues/1428) +* Changes Apriltag Axis Display order on camera preview screen, to reflect updated Z axis direction. +* The Driver Station app init button has a light teal background with the word init if + * the driver station and robot controller are connected and have the same team number + * there is at least one gamepad attached + * the timer is enabled (for an Autonomous OpMode) + +### Bug Fixes +* Fixes issue [1949](https://github.com/FIRST-Tech-Challenge/FtcRobotController/issues/1949) overwriting the group with the default group when registering a OpMode with OpModeManager.register(OpModeMeta name, Class clazz) +* Fixes issue mentioned in [1890](https://github.com/FIRST-Tech-Challenge/FtcRobotController/issues/1890) where if + for a servo you change the direction or scaleRange and send the same setPosition that was sent + before, then it wouldn't update the servo. +* Fixes an issue where Self-Inspect doesn't flag a driver station using -RC in it's name. The message is now: + * The team numbers in the robot controller and driver station names do not match, or a device name is invalid. Refer to the FTC Competition Manual for device naming rules. + ## Version 11.1 (20251231-104637) ### Enhancements @@ -132,6 +163,7 @@ The readme.md file located in the [/TeamCode/src/main/java/org/firstinspires/ftc to rename the file, the rename will fail. ### Enhancements +* Adds a configuration item for a Full Range Servo. Selecting this item expands the pulse width range from 500us to 2500us. For comparison, the legacy Servo type defines the pulse width range as 600us to 2400us. * Improved the OBJ new file creation flow workflow. The new flow allows you to easily use samples, craft new custom OpModes and make new Java classes. * Added support for gamepad edge detection. * A new sample program `ConceptGamepadEdgeDetection` demonstrates its use. diff --git a/build.dependencies.gradle b/build.dependencies.gradle index cad63e6f6d38..a01fe64d4b20 100644 --- a/build.dependencies.gradle +++ b/build.dependencies.gradle @@ -4,14 +4,14 @@ repositories { } dependencies { - implementation 'org.firstinspires.ftc:Inspection:11.1.0' - implementation 'org.firstinspires.ftc:Blocks:11.1.0' - implementation 'org.firstinspires.ftc:RobotCore:11.1.0' - implementation 'org.firstinspires.ftc:RobotServer:11.1.0' - implementation 'org.firstinspires.ftc:OnBotJava:11.1.0' - implementation 'org.firstinspires.ftc:Hardware:11.1.0' - implementation 'org.firstinspires.ftc:FtcCommon:11.1.0' - implementation 'org.firstinspires.ftc:Vision:11.1.0' + implementation 'org.firstinspires.ftc:Inspection:11.2.0' + implementation 'org.firstinspires.ftc:Blocks:11.2.0' + implementation 'org.firstinspires.ftc:RobotCore:11.2.0' + implementation 'org.firstinspires.ftc:RobotServer:11.2.0' + implementation 'org.firstinspires.ftc:OnBotJava:11.2.0' + implementation 'org.firstinspires.ftc:Hardware:11.2.0' + implementation 'org.firstinspires.ftc:FtcCommon:11.2.0' + implementation 'org.firstinspires.ftc:Vision:11.2.0' implementation 'androidx.appcompat:appcompat:1.2.0' }