From 35d4aa719283d72d34e3e9352a3fcd2cbcc44dc7 Mon Sep 17 00:00:00 2001 From: Cal Kestis Date: Mon, 21 Nov 2022 14:53:43 -0800 Subject: [PATCH] FtcRobotController v8.1 --- .../src/main/AndroidManifest.xml | 4 +- .../ConceptExploringIMUOrientation.java | 185 ++++++++++++++++++ .../external/samples/SensorBNO055IMU.java | 5 +- .../samples/SensorBNO055IMUCalibration.java | 3 + .../samples/SensorIMUNonOrthogonal.java | 183 +++++++++++++++++ .../external/samples/SensorIMUOrthogonal.java | 145 ++++++++++++++ README.md | 83 +++++++- TeamCode/build.gradle | 4 + build.dependencies.gradle | 16 +- gradle.properties | 3 + 10 files changed, 611 insertions(+), 20 deletions(-) create mode 100644 FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptExploringIMUOrientation.java create mode 100644 FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUNonOrthogonal.java create mode 100644 FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUOrthogonal.java diff --git a/FtcRobotController/src/main/AndroidManifest.xml b/FtcRobotController/src/main/AndroidManifest.xml index 7ec8ab31d417..62928518c7d5 100644 --- a/FtcRobotController/src/main/AndroidManifest.xml +++ b/FtcRobotController/src/main/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="48" + android:versionName="8.1"> diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptExploringIMUOrientation.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptExploringIMUOrientation.java new file mode 100644 index 000000000000..e19d0210a57f --- /dev/null +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptExploringIMUOrientation.java @@ -0,0 +1,185 @@ +/* +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 file 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 sample 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/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMU.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMU.java index 9102a108d872..e0022d6aa1d4 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMU.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMU.java @@ -49,13 +49,16 @@ /** * {@link SensorBNO055IMU} 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 +@Disabled // Comment this out to add to the opmode list public class SensorBNO055IMU extends LinearOpMode { //---------------------------------------------------------------------------------------------- diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMUCalibration.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMUCalibration.java index 064e8a44bffe..9daa9f7969f8 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMUCalibration.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMUCalibration.java @@ -50,6 +50,9 @@ * {@link SensorBNO055IMUCalibration} calibrates the IMU accelerometer 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 {@link BNO055IMU.SensorMode#IMU * SensorMode#IMU}), the BNO055 is internally self-calibrating and thus can be very successfully diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUNonOrthogonal.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUNonOrthogonal.java new file mode 100644 index 000000000000..78cdbabc0694 --- /dev/null +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUNonOrthogonal.java @@ -0,0 +1,183 @@ +/* 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 static com.qualcomm.hardware.rev.RevHubOrientationOnRobot.xyzOrientation; + +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; + +/** + * {@link SensorIMUNonOrthogonal} shows how to use the new universal {@link 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. + * + * 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. + * 1) 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/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUOrthogonal.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUOrthogonal.java new file mode 100644 index 000000000000..151a3ef9a1f9 --- /dev/null +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorIMUOrthogonal.java @@ -0,0 +1,145 @@ +/* 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; + +/** + * {@link SensorIMUOrthogonal} shows how to use the new universal {@link 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. + */ + + /* 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/README.md b/README.md index 3347f5af0127..51db1fefdf03 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ ## NOTICE -This repository contains the public FTC SDK for the Freight Frenzy (2021-2022) competition season. +This repository contains the public FTC SDK for the POWERPLAY (2022-2023) competition season. ## Welcome! This GitHub repository contains the source code that is used to build an Android app to control a *FIRST* Tech Challenge competition robot. To use this SDK, download/clone the entire project to your local computer. ## Getting Started -If you are new to robotics or new to the *FIRST* Tech Challenge, then you should consider reviewing the [FTC Blocks Tutorial](https://github.com/FIRST-Tech-Challenge/FtcRobotController/wiki/Blocks-Tutorial) to get familiar with how to use the control system: +If you are new to robotics or new to the *FIRST* Tech Challenge, then you should consider reviewing the [FTC Blocks Tutorial](https://ftc-docs.firstinspires.org/programming_resources/blocks/Blocks-Tutorial.html) to get familiar with how to use the control system: -      [FTC Blocks Online Tutorial](https://github.com/FIRST-Tech-Challenge/FtcRobotController/wiki/Blocks-Tutorial) +      [FTC Blocks Online Tutorial](https://ftc-docs.firstinspires.org/programming_resources/blocks/Blocks-Tutorial.html) -Even if you are an advanced Java programmer, it is helpful to start with the [FTC Blocks tutorial](https://github.com/FIRST-Tech-Challenge/FtcRobotController/wiki/Blocks-Tutorial), and then migrate to the [OnBot Java Tool](https://github.com/FIRST-Tech-Challenge/FtcRobotController/wiki/OnBot-Java-Tutorial) or to [Android Studio](https://github.com/FIRST-Tech-Challenge/FtcRobotController/wiki/Android-Studio-Tutorial) afterwards. +Even if you are an advanced Java programmer, it is helpful to start with the [FTC Blocks tutorial](https://ftc-docs.firstinspires.org/programming_resources/blocks/Blocks-Tutorial.html), and then migrate to the [OnBot Java Tool](https://ftc-docs.firstinspires.org/programming_resources/onbot_java/OnBot-Java-Tutorial.html) or to [Android Studio](https://ftc-docs.firstinspires.org/programming_resources/android_studio_java/Android-Studio-Tutorial.html) afterwards. ## Downloading the Project If you are an Android Studio programmer, there are several ways to download this repo. Note that if you use the Blocks or OnBot Java Tool to program your robot, then you do not need to download this repository. @@ -31,7 +31,7 @@ Once you have downloaded and uncompressed (if needed) your folder, you can use A ### User Documentation and Tutorials *FIRST* maintains online documentation with information and tutorials on how to use the *FIRST* Tech Challenge software and robot control system. You can access this documentation using the following link: -      [FtcRobotController Online Documentation](https://github.com/FIRST-Tech-Challenge/FtcRobotController/wiki) +      [FIRST Tech Challenge Documentation](https://ftc-docs.firstinspires.org/index.html) Note that the online documentation is an "evergreen" document that is constantly being updated and edited. It contains the most current information about the *FIRST* Tech Challenge software and control system. @@ -41,9 +41,9 @@ The Javadoc reference documentation for the FTC SDK is now available online. Cl       [FTC Javadoc Documentation](https://javadoc.io/doc/org.firstinspires.ftc) ### Online User Forum -For technical questions regarding the Control System or the FTC SDK, please visit the FTC Technology forum: +For technical questions regarding the Control System or the FTC SDK, please visit the FIRST Tech Challenge Community site: -      [FTC Technology Forum](https://ftcforum.firstinspires.org/forum/ftc-technology) +      [FIRST Tech Challenge Community](https://ftc-community.firstinspires.org/) ### Sample OpModes This project contains a large selection of Sample OpModes (robot code examples) which can be cut and pasted into your /teamcode folder to be used as-is, or modified to suit your team's needs. @@ -54,6 +54,71 @@ The readme.md file located in the [/TeamCode/src/main/java/org/firstinspires/ftc # Release Information +## Version 8.1 (20221121-115119) + +### Breaking Changes +* Deprecates the `OpMode` fields `msStuckDetectInit`, `msStuckDetectInitLoop`, `msStuckDetectStart`, `msStuckDetectLoop`, and `msStuckDetectStop`. + * Op Modes no longer have a time limit for `init()`, `init_loop()`, `start()` or `loop()`, so the fields corresponding to those methods are no longer used. + * `stop()` still has a time limit, but it is now hardcoded to be 1 second, and cannot be changed using `msStuckDetectStop`. +* Deprecates the `OpMode` methods `internalPreInit()`, `internalPostInitLoop()`, and `internalPostLoop()`. + * Iterative `OpMode`s will continue to call these methods in case they were overridden. + * These methods will not be called at all for `LinearOpMode`s. +* Deprecates (and stops respecting) `DeviceProperties.xmlTagAliases`. + +### Enhancements +* Adds a new `IMU` interface to Blocks and Java that can be used with both the original BNO055 IMU + included in all older Control Hubs and Expansion Hubs, and the new alternative BHI260AP IMU. + * You can determine which type of IMU is in your Control Hub by navigating to the Manage page of the web interface. + * To learn how to use the new `IMU` interface, see https://ftc-docs.firstinspires.org/programming_resources/imu/imu.html. The `SensorIMU` Blocks sample was also updated to use the new `IMU` interface, and the following Java samples were added: + * `SensorIMUOrthogonal` + * Use this sample if your REV Hub is mounted so that it is parallel or perpendicular to the + bottom of your robot. + * `SensorIMUNonOrthogonal` + * Use this sample if your REV Hub is mounted to your robot in any other orientation + * `ConceptExploringIMUOrientations` + * This Op Mode is a tool to help you understand how the orthogonal orientations work, and + which one applies to your robot. + * The BHI260AP IMU can only be accessed via the new `IMU` interface. The BNO055 IMU can be + programmed using the new `IMU` interface, or you can continue to program it using the old `BNO055IMU` + interface. If you want to be able to quickly switch to a new Control Hub that may contain the + BHI260AP IMU, you should migrate your code to use the new `IMU` interface. + * Unlike the old `BNO055IMU` interface, which only worked correctly when the REV Hub was mounted flat + on your robot, the `IMU` interface allows you to specify the orientation of the REV Hub on your + robot. It will account for this, and give you your orientation in a Robot Coordinate System, + instead of a special coordinate system for the REV Hub. As a result, your pitch and yaw will be + 0 when your *robot* is level, instead of when the REV Hub is level, which will result in much + more reliable orientation angle values for most mounting orientations. + * Because of the new robot-centric coordinate system, the pitch and roll angles returned by the + `IMU` interface will be different from the ones returned by the `BNO055IMU` interface. When you are + migrating your code, pay careful attention to the documentation. + * If you have calibrated your BNO055, you can provide that calibration data to the new `IMU` + interface by passing a `BNO055IMUNew.Parameters` instance to `IMU.initialize()`. + * The `IMU` interface is also suitable for implementation by third-party vendors for IMUs that + support providing the orientation in the form of a quaternion. +* Iterative `OpMode`s (as opposed to `LinearOpMode`s) now run on a dedicated thread. + * Cycle times should not be as impacted by everything else going on in the system. + * Slow `OpMode`s can no longer increase the amount of time it takes to process network commands, and vice versa. + * The `init()`, `init_loop()`, `start()` and `loop()` methods no longer need to return within a certain time frame. +* BNO055 IMU legacy driver: restores the ability to initialize in one Op Mode, and then have another Op Mode re-use that + initialization. This allows you to maintain the 0-yaw position between Op Modes, if desired. +* Allows customized versions of device drivers in the FTC SDK to use the same XML tag. + * Before, if you wanted to customize a device driver, you had to copy it to a new class _and_ give + it a new XML tag. Giving it a new XML tag meant that to switch which driver was being used, you + had to modify your configuration file. + * Now, to use your custom driver, all you have to do is specify your custom driver's class when + calling `hardwareMap.get()`. To go back to the original driver, specify the original driver + class. If you specify an interface that is implemented by both the original driver and the + custom driver, there is no guarantee about which implementation will be returned. + +### Bug Fixes +* Fixes accessing the "Manage TensorFlow Lite Models" and "Manage Sounds" links and performing + Blocks and OnBotJava Op Mode downloads from the REV Hardware Client. +* Fixes issue where an I2C device driver would be auto-initialized using the parameters assigned in + a previous Op Mode run. +* Improves Driver Station popup menu placement in the landscape layout. +* Fixes NullPointerException when attempting to get a non-configured BNO055 IMU in a Blocks Op Mode on an RC phone. +* Fixes problem with Blocks if a variable is named `orientation`. + ## Version 8.0 (20220907-131644) ### Breaking Changes @@ -88,8 +153,8 @@ The readme.md file located in the [/TeamCode/src/main/java/org/firstinspires/ftc * The exception text in the popup window is both zoomable and scrollable just like a webpage. * Pressing the "OK" button in the popup window will return to the main screen of the Driver Station and allow an Op Mode to be run again immediately, without the need to perform a "Restart Robot" * Adds new Java sample to demonstrate using a hardware class to abstract robot actuators, and share them across multiple Op Modes. - * Sample Op Mode is [/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptExternalHardwareClass.java](ConceptExternalHardwareClass.java) - * Abstracted hardware class is [/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotHardware.java](RobotHardware.java)) + * Sample Op Mode is [ConceptExternalHardwareClass.java](FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptExternalHardwareClass.java) + * Abstracted hardware class is [RobotHardware.java](FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/RobotHardware.java) * Updates RobotAutoDriveByGyro_Linear Java sample to use REV Control/Expansion hub IMU. * Updates Vuforia samples to reference PowerPlay assets and have correct names and field locations of image targets. * Updates TensorFlow samples to reference PowerPlay assets. diff --git a/TeamCode/build.gradle b/TeamCode/build.gradle index fc50d0a9b55d..436ce671e98f 100644 --- a/TeamCode/build.gradle +++ b/TeamCode/build.gradle @@ -17,6 +17,10 @@ apply from: '../build.dependencies.gradle' android { namespace = 'org.firstinspires.ftc.teamcode' + + packagingOptions { + jniLibs.useLegacyPackaging true + } } dependencies { diff --git a/build.dependencies.gradle b/build.dependencies.gradle index 56f72c905c20..eeab776644fc 100644 --- a/build.dependencies.gradle +++ b/build.dependencies.gradle @@ -7,14 +7,14 @@ repositories { } dependencies { - implementation 'org.firstinspires.ftc:Inspection:8.0.0' - implementation 'org.firstinspires.ftc:Blocks:8.0.0' - implementation 'org.firstinspires.ftc:Tfod:8.0.0' - implementation 'org.firstinspires.ftc:RobotCore:8.0.0' - implementation 'org.firstinspires.ftc:RobotServer:8.0.0' - implementation 'org.firstinspires.ftc:OnBotJava:8.0.0' - implementation 'org.firstinspires.ftc:Hardware:8.0.0' - implementation 'org.firstinspires.ftc:FtcCommon:8.0.0' + implementation 'org.firstinspires.ftc:Inspection:8.1.0' + implementation 'org.firstinspires.ftc:Blocks:8.1.0' + implementation 'org.firstinspires.ftc:Tfod:8.1.0' + implementation 'org.firstinspires.ftc:RobotCore:8.1.0' + implementation 'org.firstinspires.ftc:RobotServer:8.1.0' + implementation 'org.firstinspires.ftc:OnBotJava:8.1.0' + implementation 'org.firstinspires.ftc:Hardware:8.1.0' + implementation 'org.firstinspires.ftc:FtcCommon:8.1.0' implementation 'org.tensorflow:tensorflow-lite-task-vision:0.2.0' implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'org.firstinspires.ftc:gameAssets-PowerPlay:1.0.0' diff --git a/gradle.properties b/gradle.properties index 0bd596f2614f..104e43cae8d5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,3 +5,6 @@ android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true + +# Allow Gradle to use up to 1 GB of RAM +org.gradle.jvmargs=-Xmx1024M