diff --git a/FtcRobotController/build.gradle b/FtcRobotController/build.gradle index b73fbe4f1a9..13a0bb952f5 100644 --- a/FtcRobotController/build.gradle +++ b/FtcRobotController/build.gradle @@ -11,7 +11,6 @@ android { } compileSdkVersion 23 - buildToolsVersion '25.0.3' compileOptions { sourceCompatibility JavaVersion.VERSION_1_7 diff --git a/FtcRobotController/build.release.gradle b/FtcRobotController/build.release.gradle index 4b3fe906d63..1cb2035ed48 100644 --- a/FtcRobotController/build.release.gradle +++ b/FtcRobotController/build.release.gradle @@ -4,6 +4,5 @@ dependencies { compile (name:'RobotCore-release', ext: 'aar') compile (name:'Hardware-release', ext: 'aar') compile (name:'FtcCommon-release', ext: 'aar') - compile (name:'Analytics-release', ext:'aar') compile (name:'WirelessP2p-release', ext:'aar') } diff --git a/FtcRobotController/src/main/AndroidManifest.xml b/FtcRobotController/src/main/AndroidManifest.xml index 63fa417b182..387f1bb3a7e 100644 --- a/FtcRobotController/src/main/AndroidManifest.xml +++ b/FtcRobotController/src/main/AndroidManifest.xml @@ -2,8 +2,8 @@ + android:versionCode="28" + android:versionName="4.0"> diff --git a/FtcRobotController/src/main/assets/RoverRuckus.dat b/FtcRobotController/src/main/assets/RoverRuckus.dat new file mode 100755 index 00000000000..461add830d0 Binary files /dev/null and b/FtcRobotController/src/main/assets/RoverRuckus.dat differ diff --git a/FtcRobotController/src/main/assets/RoverRuckus.xml b/FtcRobotController/src/main/assets/RoverRuckus.xml new file mode 100755 index 00000000000..05eac7ea3a8 --- /dev/null +++ b/FtcRobotController/src/main/assets/RoverRuckus.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptCompassCalibration.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptCompassCalibration.java index b5920f9839c..cd1da0a85de 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptCompassCalibration.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptCompassCalibration.java @@ -29,9 +29,9 @@ 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.eventloop.opmode.TeleOp; import com.qualcomm.robotcore.hardware.CompassSensor; import com.qualcomm.robotcore.util.ElapsedTime; @@ -52,7 +52,7 @@ * Remove or comment out the @Disabled line to add this opmode to the Driver Station OpMode list */ -@Autonomous(name="Concept: Compass Calibration", group="Concept") +@TeleOp(name="Concept: Compass Calibration", group="Concept") @Disabled public class ConceptCompassCalibration extends LinearOpMode { diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptDIMAsIndicator.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptDIMAsIndicator.java index 699d2e5d0a0..75b6ad44583 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptDIMAsIndicator.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptDIMAsIndicator.java @@ -29,9 +29,9 @@ 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.eventloop.opmode.TeleOp; import com.qualcomm.robotcore.hardware.DeviceInterfaceModule; import com.qualcomm.robotcore.util.ElapsedTime; @@ -51,7 +51,7 @@ * Use Android Studios 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 = "Concept: DIM As Indicator", group = "Concept") +@TeleOp(name = "Concept: DIM As Indicator", group = "Concept") @Disabled public class ConceptDIMAsIndicator extends LinearOpMode { diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptNullOp.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptNullOp.java index ee83ec00d61..2f846959f34 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptNullOp.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptNullOp.java @@ -29,9 +29,9 @@ 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.OpMode; +import com.qualcomm.robotcore.eventloop.opmode.TeleOp; import com.qualcomm.robotcore.util.ElapsedTime; import java.text.SimpleDateFormat; @@ -40,7 +40,7 @@ /** * Demonstrates empty OpMode */ -@Autonomous(name = "Concept: NullOp", group = "Concept") +@TeleOp(name = "Concept: NullOp", group = "Concept") @Disabled public class ConceptNullOp extends OpMode { diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRampMotorSpeed.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRampMotorSpeed.java index 45085402291..0a8f3dcc28c 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRampMotorSpeed.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRampMotorSpeed.java @@ -29,9 +29,9 @@ 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.eventloop.opmode.TeleOp; import com.qualcomm.robotcore.hardware.DcMotor; /** @@ -46,7 +46,7 @@ * 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 = "Concept: Ramp Motor Speed", group = "Concept") +@TeleOp(name = "Concept: Ramp Motor Speed", group = "Concept") @Disabled public class ConceptRampMotorSpeed extends LinearOpMode { diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRegisterOpModes.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRegisterOpModes.java index a0046baf361..2427c7fb45a 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRegisterOpModes.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptRegisterOpModes.java @@ -111,5 +111,8 @@ public static void registerMyOpModes(OpModeManager manager) { // manager.register("Scan Servo", ConceptScanServo.class); // manager.register("Telemetry", ConceptTelemetry.class); // manager.register("Vuforia Navigation", ConceptVuforiaNavigation.class); + // manager.register("Vuforia Navigation Webcam", ConceptVuforiaNavigationWebcam.class); + // manager.register("Vuforia VuMarkID", ConceptVuforiaVuMarkIdentification.class); + // manager.register("Vuforia VuMarkID Webcam", ConceptVuforiaVuMarkIdentificationWebcam.class); } } diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptScanServo.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptScanServo.java index 0f4e2355102..ce389cef5d0 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptScanServo.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptScanServo.java @@ -29,9 +29,9 @@ 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.eventloop.opmode.TeleOp; import com.qualcomm.robotcore.hardware.Servo; /** @@ -48,7 +48,7 @@ * 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 = "Concept: Scan Servo", group = "Concept") +@TeleOp(name = "Concept: Scan Servo", group = "Concept") @Disabled public class ConceptScanServo extends LinearOpMode { diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptTelemetry.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptTelemetry.java index 5994561175e..d3b468282d8 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptTelemetry.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptTelemetry.java @@ -29,9 +29,9 @@ 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.eventloop.opmode.TeleOp; import com.qualcomm.robotcore.hardware.VoltageSensor; import com.qualcomm.robotcore.util.ElapsedTime; @@ -47,7 +47,7 @@ * * @see Telemetry */ -@Autonomous(name = "Concept: Telemetry", group = "Concept") +@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 */ diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVuMarkIdentification.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVuMarkIdentification.java index 041e2a20a85..f0d735bfb8d 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVuMarkIdentification.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVuMarkIdentification.java @@ -28,7 +28,7 @@ */ package org.firstinspires.ftc.robotcontroller.external.samples; -import com.qualcomm.robotcore.eventloop.opmode.Autonomous; +import com.qualcomm.robotcore.eventloop.opmode.TeleOp; import com.qualcomm.robotcore.eventloop.opmode.Disabled; import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode; @@ -65,7 +65,7 @@ * is explained in {@link ConceptVuforiaNavigation}. */ -@Autonomous(name="Concept: VuMark Id", group ="Concept") +@TeleOp(name="Concept: VuMark Id", group ="Concept") @Disabled public class ConceptVuMarkIdentification extends LinearOpMode { @@ -83,7 +83,6 @@ public class ConceptVuMarkIdentification extends LinearOpMode { /* * To start up Vuforia, tell it the view that we wish to use for camera monitor (on the RC phone); - * If no camera monitor is desired, use the parameterless constructor instead (commented out below). */ int cameraMonitorViewId = hardwareMap.appContext.getResources().getIdentifier("cameraMonitorViewId", "id", hardwareMap.appContext.getPackageName()); VuforiaLocalizer.Parameters parameters = new VuforiaLocalizer.Parameters(cameraMonitorViewId); @@ -101,9 +100,9 @@ public class ConceptVuMarkIdentification extends LinearOpMode { * random data. As an example, here is a example of a fragment of a valid key: * ... yIgIzTqZ4mWjk9wd3cZO9T1axEqzuhxoGlfOOI2dRzKS4T0hQ8kT ... * Once you've obtained a license key, copy the string from the Vuforia web site - * and paste it in to your code onthe next line, between the double quotes. + * and paste it in to your code on the next line, between the double quotes. */ - parameters.vuforiaLicenseKey = "ATsODcD/////AAAAAVw2lR...d45oGpdljdOh5LuFB9nDNfckoxb8COxKSFX"; + parameters.vuforiaLicenseKey = " -- YOUR NEW VUFORIA KEY GOES HERE --- "; /* * We also indicate which camera on the RC that we wish to use. @@ -111,7 +110,12 @@ public class ConceptVuMarkIdentification extends LinearOpMode { * for a competition robot, the front camera might be more convenient. */ parameters.cameraDirection = VuforiaLocalizer.CameraDirection.BACK; - this.vuforia = ClassFactory.createVuforiaLocalizer(parameters); + + /** + * Instantiate the Vuforia engine + */ + vuforia = ClassFactory.getInstance().createVuforia(parameters); + /** * Load the data set containing the VuMarks for Relic Recovery. There's only one trackable diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVuMarkIdentificationWebcam.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVuMarkIdentificationWebcam.java new file mode 100644 index 00000000000..866261f223c --- /dev/null +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVuMarkIdentificationWebcam.java @@ -0,0 +1,194 @@ +/* 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.TeleOp; +import com.qualcomm.robotcore.eventloop.opmode.Disabled; +import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode; + +import org.firstinspires.ftc.robotcore.external.ClassFactory; +import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName; +import org.firstinspires.ftc.robotcore.external.matrices.OpenGLMatrix; +import org.firstinspires.ftc.robotcore.external.matrices.VectorF; +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.RelicRecoveryVuMark; +import org.firstinspires.ftc.robotcore.external.navigation.VuMarkInstanceId; +import org.firstinspires.ftc.robotcore.external.navigation.VuforiaLocalizer; +import org.firstinspires.ftc.robotcore.external.navigation.VuforiaTrackable; +import org.firstinspires.ftc.robotcore.external.navigation.VuforiaTrackableDefaultListener; +import org.firstinspires.ftc.robotcore.external.navigation.VuforiaTrackables; + +/** + * This OpMode illustrates the basics of using the Vuforia engine to determine + * the identity of Vuforia VuMarks encountered on the field. The code is structured as + * a LinearOpMode. It shares much structure with {@link ConceptVuforiaNavigationWebcam}; we do not here + * duplicate the core Vuforia documentation found there, but rather instead focus on the + * differences between the use of Vuforia for navigation vs VuMark identification. + * + * @see ConceptVuforiaNavigationWebcam + * @see VuforiaLocalizer + * @see VuforiaTrackableDefaultListener + * see ftc_app/doc/tutorial/FTC_FieldCoordinateSystemDefinition.pdf + * + * 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. + * + * IMPORTANT: In order to use this OpMode, you need to obtain your own Vuforia license key as + * is explained in {@link ConceptVuforiaNavigationWebcam}. + */ + +@TeleOp(name="Concept: VuMark Id Webcam", group ="Concept") +@Disabled +public class ConceptVuMarkIdentificationWebcam extends LinearOpMode { + + public static final String TAG = "Vuforia VuMark Sample"; + + OpenGLMatrix lastLocation = null; + + /** + * {@link #vuforia} is the variable we will use to store our instance of the Vuforia + * localization engine. + */ + VuforiaLocalizer vuforia; + + /** + * This is the webcam we are to use. As with other hardware devices such as motors and + * servos, this device is identified using the robot configuration tool in the FTC application. + */ + WebcamName webcamName; + + @Override public void runOpMode() { + + /* + * Retrieve the camera we are to use. + */ + webcamName = hardwareMap.get(WebcamName.class, "Webcam 1"); + + /* + * To start up Vuforia, tell it the view that we wish to use for camera monitor (on the RC phone); + * If no camera monitor is desired, use the parameterless constructor instead (commented out below). + */ + int cameraMonitorViewId = hardwareMap.appContext.getResources().getIdentifier("cameraMonitorViewId", "id", hardwareMap.appContext.getPackageName()); + VuforiaLocalizer.Parameters parameters = new VuforiaLocalizer.Parameters(cameraMonitorViewId); + + // OR... Do Not Activate the Camera Monitor View, to save power + // VuforiaLocalizer.Parameters parameters = new VuforiaLocalizer.Parameters(); + + /* + * IMPORTANT: You need to obtain your own license key to use Vuforia. The string below with which + * 'parameters.vuforiaLicenseKey' is initialized is for illustration only, and will not function. + * A Vuforia 'Development' license key, can be obtained free of charge from the Vuforia developer + * web site at https://developer.vuforia.com/license-manager. + * + * Vuforia license keys are always 380 characters long, and look as if they contain mostly + * random data. As an example, here is a example of a fragment of a valid key: + * ... yIgIzTqZ4mWjk9wd3cZO9T1axEqzuhxoGlfOOI2dRzKS4T0hQ8kT ... + * Once you've obtained a license key, copy the string from the Vuforia web site + * and paste it in to your code on the next line, between the double quotes. + */ + parameters.vuforiaLicenseKey = " -- YOUR NEW VUFORIA KEY GOES HERE --- "; + + + /** + * We also indicate which camera on the RC we wish to use. For pedagogical purposes, + * we use the same logic as in {@link ConceptVuforiaNavigationWebcam}. + */ + parameters.cameraName = webcamName; + this.vuforia = ClassFactory.getInstance().createVuforia(parameters); + + /** + * Load the data set containing the VuMarks for Relic Recovery. There's only one trackable + * in this data set: all three of the VuMarks in the game were created from this one template, + * but differ in their instance id information. + * @see VuMarkInstanceId + */ + VuforiaTrackables relicTrackables = this.vuforia.loadTrackablesFromAsset("RelicVuMark"); + VuforiaTrackable relicTemplate = relicTrackables.get(0); + relicTemplate.setName("relicVuMarkTemplate"); // can help in debugging; otherwise not necessary + + telemetry.addData(">", "Press Play to start"); + telemetry.update(); + waitForStart(); + + relicTrackables.activate(); + + while (opModeIsActive()) { + + /** + * See if any of the instances of {@link relicTemplate} are currently visible. + * {@link RelicRecoveryVuMark} is an enum which can have the following values: + * UNKNOWN, LEFT, CENTER, and RIGHT. When a VuMark is visible, something other than + * UNKNOWN will be returned by {@link RelicRecoveryVuMark#from(VuforiaTrackable)}. + */ + RelicRecoveryVuMark vuMark = RelicRecoveryVuMark.from(relicTemplate); + if (vuMark != RelicRecoveryVuMark.UNKNOWN) { + + /* Found an instance of the template. In the actual game, you will probably + * loop until this condition occurs, then move on to act accordingly depending + * on which VuMark was visible. */ + telemetry.addData("VuMark", "%s visible", vuMark); + + /* For fun, we also exhibit the navigational pose. In the Relic Recovery game, + * it is perhaps unlikely that you will actually need to act on this pose information, but + * we illustrate it nevertheless, for completeness. */ + OpenGLMatrix pose = ((VuforiaTrackableDefaultListener)relicTemplate.getListener()).getFtcCameraFromTarget(); + telemetry.addData("Pose", format(pose)); + + /* We further illustrate how to decompose the pose into useful rotational and + * translational components */ + if (pose != null) { + VectorF trans = pose.getTranslation(); + Orientation rot = Orientation.getOrientation(pose, AxesReference.EXTRINSIC, AxesOrder.XYZ, AngleUnit.DEGREES); + + // Extract the X, Y, and Z components of the offset of the target relative to the robot + double tX = trans.get(0); + double tY = trans.get(1); + double tZ = trans.get(2); + + // Extract the rotational components of the target relative to the robot + double rX = rot.firstAngle; + double rY = rot.secondAngle; + double rZ = rot.thirdAngle; + } + } + else { + telemetry.addData("VuMark", "not visible"); + } + + telemetry.update(); + } + } + + String format(OpenGLMatrix transformationMatrix) { + return (transformationMatrix != null) ? transformationMatrix.formatAsTransform() : "null"; + } +} diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVuforiaNavRoverRuckus.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVuforiaNavRoverRuckus.java new file mode 100644 index 00000000000..eb21cf78e9f --- /dev/null +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVuforiaNavRoverRuckus.java @@ -0,0 +1,311 @@ +/* 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.LinearOpMode; +import com.qualcomm.robotcore.eventloop.opmode.TeleOp; +import com.qualcomm.robotcore.eventloop.opmode.Disabled; + +import org.firstinspires.ftc.robotcore.external.ClassFactory; +import org.firstinspires.ftc.robotcore.external.matrices.OpenGLMatrix; +import org.firstinspires.ftc.robotcore.external.matrices.VectorF; +import org.firstinspires.ftc.robotcore.external.navigation.Orientation; +import org.firstinspires.ftc.robotcore.external.navigation.VuforiaLocalizer; +import org.firstinspires.ftc.robotcore.external.navigation.VuforiaTrackable; +import org.firstinspires.ftc.robotcore.external.navigation.VuforiaTrackableDefaultListener; +import org.firstinspires.ftc.robotcore.external.navigation.VuforiaTrackables; + +import static org.firstinspires.ftc.robotcore.external.navigation.AngleUnit.DEGREES; +import static org.firstinspires.ftc.robotcore.external.navigation.AxesOrder.XYZ; +import static org.firstinspires.ftc.robotcore.external.navigation.AxesOrder.YZX; +import static org.firstinspires.ftc.robotcore.external.navigation.AxesReference.EXTRINSIC; +import static org.firstinspires.ftc.robotcore.external.navigation.VuforiaLocalizer.CameraDirection.BACK; +import static org.firstinspires.ftc.robotcore.external.navigation.VuforiaLocalizer.CameraDirection.FRONT; + +import java.util.ArrayList; +import java.util.List; + + +/** + * This 2018-2019 OpMode illustrates the basics of using the Vuforia localizer to determine + * positioning and orientation of robot on the FTC field. + * The code is structured as a LinearOpMode + * + * Vuforia uses the phone's camera to inspect it's surroundings, and attempt to locate target images. + * + * When images are located, Vuforia is able to determine the position and orientation of the + * image relative to the camera. This sample code than combines that information with a + * knowledge of where the target images are on the field, to determine the location of the camera. + * + * This example assumes a "square" field configuration where the red and blue alliance stations + * are on opposite walls of each other. + * + * From the Audience perspective, the Red Alliance station is on the right and the + * Blue Alliance Station is on the left. + + * The four vision targets are located in the center of each of the perimeter walls with + * the images facing inwards towards the robots: + * - BlueRover is the Mars Rover image target on the wall closest to the blue alliance + * - RedFootprint is the Lunar Footprint target on the wall closest to the red alliance + * - FrontCraters is the Lunar Craters image target on the wall closest to the audience + * - BackSpace is the Deep Space image target on the wall farthest from the audience + * + * A final calculation then uses the location of the camera on the robot to determine the + * robot's location and orientation on the field. + * + * @see VuforiaLocalizer + * @see VuforiaTrackableDefaultListener + * see ftc_app/doc/tutorial/FTC_FieldCoordinateSystemDefinition.pdf + * + * 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. + * + * IMPORTANT: In order to use this OpMode, you need to obtain your own Vuforia license key as + * is explained below. + */ + +@TeleOp(name="Concept: Vuforia Rover Nav", group ="Concept") +@Disabled +public class ConceptVuforiaNavRoverRuckus extends LinearOpMode { + + /* + * IMPORTANT: You need to obtain your own license key to use Vuforia. The string below with which + * 'parameters.vuforiaLicenseKey' is initialized is for illustration only, and will not function. + * A Vuforia 'Development' license key, can be obtained free of charge from the Vuforia developer + * web site at https://developer.vuforia.com/license-manager. + * + * Vuforia license keys are always 380 characters long, and look as if they contain mostly + * random data. As an example, here is a example of a fragment of a valid key: + * ... yIgIzTqZ4mWjk9wd3cZO9T1axEqzuhxoGlfOOI2dRzKS4T0hQ8kT ... + * Once you've obtained a license key, copy the string from the Vuforia web site + * and paste it in to your code on the next line, between the double quotes. + */ + private static final String VUFORIA_KEY = " -- YOUR NEW VUFORIA KEY GOES HERE --- "; + + // Since ImageTarget trackables use mm to specifiy their dimensions, we must use mm for all the physical dimension. + // We will define some constants and conversions here + private static final float mmPerInch = 25.4f; + private static final float mmFTCFieldWidth = (12*6) * mmPerInch; // the width of the FTC field (from the center point to the outer panels) + private static final float mmTargetHeight = (6) * mmPerInch; // the height of the center of the target image above the floor + + // Select which camera you want use. The FRONT camera is the one on the same side as the screen. + // Valid choices are: BACK or FRONT + private static final VuforiaLocalizer.CameraDirection CAMERA_CHOICE = BACK; + + private OpenGLMatrix lastLocation = null; + private boolean targetVisible = false; + + /** + * {@link #vuforia} is the variable we will use to store our instance of the Vuforia + * localization engine. + */ + VuforiaLocalizer vuforia; + + @Override public void runOpMode() { + /* + * Configure Vuforia by creating a Parameter object, and passing it to the Vuforia engine. + * We can pass Vuforia the handle to a camera preview resource (on the RC phone); + * If no camera monitor is desired, use the parameterless constructor instead (commented out below). + */ + int cameraMonitorViewId = hardwareMap.appContext.getResources().getIdentifier("cameraMonitorViewId", "id", hardwareMap.appContext.getPackageName()); + VuforiaLocalizer.Parameters parameters = new VuforiaLocalizer.Parameters(cameraMonitorViewId); + + // VuforiaLocalizer.Parameters parameters = new VuforiaLocalizer.Parameters(); + + parameters.vuforiaLicenseKey = VUFORIA_KEY ; + parameters.cameraDirection = CAMERA_CHOICE; + + // Instantiate the Vuforia engine + vuforia = ClassFactory.getInstance().createVuforia(parameters); + + // Load the data sets that for the trackable objects. These particular data + // sets are stored in the 'assets' part of our application. + VuforiaTrackables targetsRoverRuckus = this.vuforia.loadTrackablesFromAsset("RoverRuckus"); + VuforiaTrackable blueRover = targetsRoverRuckus.get(0); + blueRover.setName("Blue-Rover"); + VuforiaTrackable redFootprint = targetsRoverRuckus.get(1); + redFootprint.setName("Red-Footprint"); + VuforiaTrackable frontCraters = targetsRoverRuckus.get(2); + frontCraters.setName("Front-Craters"); + VuforiaTrackable backSpace = targetsRoverRuckus.get(3); + backSpace.setName("Back-Space"); + + // For convenience, gather together all the trackable objects in one easily-iterable collection */ + List allTrackables = new ArrayList(); + allTrackables.addAll(targetsRoverRuckus); + + /** + * In order for localization to work, we need to tell the system where each target is on the field, and + * where the phone resides on the robot. These specifications are in the form of transformation matrices. + * Transformation matrices are a central, important concept in the math here involved in localization. + * See Transformation Matrix + * for detailed information. Commonly, you'll encounter transformation matrices as instances + * of the {@link OpenGLMatrix} class. + * + * If you are standing in the Red Alliance Station looking towards the center of the field, + * - The X axis runs from your left to the right. (positive from the center to the right) + * - The Y axis runs from the Red Alliance Station towards the other side of the field + * where the Blue Alliance Station is. (Positive is from the center, towards the BlueAlliance station) + * - The Z axis runs from the floor, upwards towards the ceiling. (Positive is above the floor) + * + * This Rover Ruckus sample places a specific target in the middle of each perimeter wall. + * + * Before being transformed, each target image is conceptually located at the origin of the field's + * coordinate system (the center of the field), facing up. + */ + + /** + * To place the BlueRover target in the middle of the blue perimeter wall: + * - First we rotate it 90 around the field's X axis to flip it upright. + * - Then, we translate it along the Y axis to the blue perimeter wall. + */ + OpenGLMatrix blueRoverLocationOnField = OpenGLMatrix + .translation(0, mmFTCFieldWidth, mmTargetHeight) + .multiplied(Orientation.getRotationMatrix(EXTRINSIC, XYZ, DEGREES, 90, 0, 0)); + blueRover.setLocation(blueRoverLocationOnField); + + /** + * To place the RedFootprint target in the middle of the red perimeter wall: + * - First we rotate it 90 around the field's X axis to flip it upright. + * - Second, we rotate it 180 around the field's Z axis so the image is flat against the red perimeter wall + * and facing inwards to the center of the field. + * - Then, we translate it along the negative Y axis to the red perimeter wall. + */ + OpenGLMatrix redFootprintLocationOnField = OpenGLMatrix + .translation(0, -mmFTCFieldWidth, mmTargetHeight) + .multiplied(Orientation.getRotationMatrix(EXTRINSIC, XYZ, DEGREES, 90, 0, 180)); + redFootprint.setLocation(redFootprintLocationOnField); + + /** + * To place the FrontCraters target in the middle of the front perimeter wall: + * - First we rotate it 90 around the field's X axis to flip it upright. + * - Second, we rotate it 90 around the field's Z axis so the image is flat against the front wall + * and facing inwards to the center of the field. + * - Then, we translate it along the negative X axis to the front perimeter wall. + */ + OpenGLMatrix frontCratersLocationOnField = OpenGLMatrix + .translation(-mmFTCFieldWidth, 0, mmTargetHeight) + .multiplied(Orientation.getRotationMatrix(EXTRINSIC, XYZ, DEGREES, 90, 0 , 90)); + frontCraters.setLocation(frontCratersLocationOnField); + + /** + * To place the BackSpace target in the middle of the back perimeter wall: + * - First we rotate it 90 around the field's X axis to flip it upright. + * - Second, we rotate it -90 around the field's Z axis so the image is flat against the back wall + * and facing inwards to the center of the field. + * - Then, we translate it along the X axis to the back perimeter wall. + */ + OpenGLMatrix backSpaceLocationOnField = OpenGLMatrix + .translation(mmFTCFieldWidth, 0, mmTargetHeight) + .multiplied(Orientation.getRotationMatrix(EXTRINSIC, XYZ, DEGREES, 90, 0, -90)); + backSpace.setLocation(backSpaceLocationOnField); + + /** + * Create a transformation matrix describing where the phone is on the robot. + * + * The coordinate frame for the robot looks the same as the field. + * The robot's "forward" direction is facing out along X axis, with the LEFT side facing out along the Y axis. + * Z is UP on the robot. This equates to a bearing angle of Zero degrees. + * + * The phone starts out lying flat, with the screen facing Up and with the physical top of the phone + * pointing to the LEFT side of the Robot. It's very important when you test this code that the top of the + * camera is pointing to the left side of the robot. The rotation angles don't work if you flip the phone. + * + * If using the rear (High Res) camera: + * We need to rotate the camera around it's long axis to bring the rear camera forward. + * This requires a negative 90 degree rotation on the Y axis + * + * If using the Front (Low Res) camera + * We need to rotate the camera around it's long axis to bring the FRONT camera forward. + * This requires a Positive 90 degree rotation on the Y axis + * + * Next, translate the camera lens to where it is on the robot. + * In this example, it is centered (left to right), but 110 mm forward of the middle of the robot, and 200 mm above ground level. + */ + + final int CAMERA_FORWARD_DISPLACEMENT = 110; // eg: Camera is 110 mm in front of robot center + final int CAMERA_VERTICAL_DISPLACEMENT = 200; // eg: Camera is 200 mm above ground + final int CAMERA_LEFT_DISPLACEMENT = 0; // eg: Camera is ON the robot's center line + + OpenGLMatrix phoneLocationOnRobot = OpenGLMatrix + .translation(CAMERA_FORWARD_DISPLACEMENT, CAMERA_LEFT_DISPLACEMENT, CAMERA_VERTICAL_DISPLACEMENT) + .multiplied(Orientation.getRotationMatrix(EXTRINSIC, YZX, DEGREES, + CAMERA_CHOICE == FRONT ? 90 : -90, 0, 0)); + + /** Let all the trackable listeners know where the phone is. */ + for (VuforiaTrackable trackable : allTrackables) + { + ((VuforiaTrackableDefaultListener)trackable.getListener()).setPhoneInformation(phoneLocationOnRobot, parameters.cameraDirection); + } + + /** Wait for the game to begin */ + telemetry.addData(">", "Press Play to start tracking"); + telemetry.update(); + waitForStart(); + + /** Start tracking the data sets we care about. */ + targetsRoverRuckus.activate(); + while (opModeIsActive()) { + + // check all the trackable target to see which one (if any) is visible. + targetVisible = false; + for (VuforiaTrackable trackable : allTrackables) { + if (((VuforiaTrackableDefaultListener)trackable.getListener()).isVisible()) { + telemetry.addData("Visible Target", trackable.getName()); + targetVisible = true; + + // getUpdatedRobotLocation() will return null if no new information is available since + // the last time that call was made, or if the trackable is not currently visible. + OpenGLMatrix robotLocationTransform = ((VuforiaTrackableDefaultListener)trackable.getListener()).getUpdatedRobotLocation(); + if (robotLocationTransform != null) { + lastLocation = robotLocationTransform; + } + break; + } + } + + // Provide feedback as to where the robot is located (if we know). + if (targetVisible) { + // express position (translation) of robot in inches. + VectorF translation = lastLocation.getTranslation(); + telemetry.addData("Pos (in)", "{X, Y, Z} = %.1f, %.1f, %.1f", + translation.get(0) / mmPerInch, translation.get(1) / mmPerInch, translation.get(2) / mmPerInch); + + // express the rotation of the robot in degrees. + Orientation rotation = Orientation.getOrientation(lastLocation, EXTRINSIC, XYZ, DEGREES); + telemetry.addData("Rot (deg)", "{Roll, Pitch, Heading} = %.0f, %.0f, %.0f", rotation.firstAngle, rotation.secondAngle, rotation.thirdAngle); + } + else { + telemetry.addData("Visible Target", "none"); + } + telemetry.update(); + } + } +} diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVuforiaNavigation.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVuforiaNavigation.java index 0fb2c42ceb5..81ab6b68331 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVuforiaNavigation.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVuforiaNavigation.java @@ -29,7 +29,7 @@ package org.firstinspires.ftc.robotcontroller.external.samples; -import com.qualcomm.robotcore.eventloop.opmode.Autonomous; +import com.qualcomm.robotcore.eventloop.opmode.TeleOp; import com.qualcomm.robotcore.eventloop.opmode.Disabled; import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode; import com.qualcomm.robotcore.util.RobotLog; @@ -80,7 +80,7 @@ * is explained below. */ -@Autonomous(name="Concept: Vuforia Navigation", group ="Concept") +@TeleOp(name="Concept: Vuforia Navigation", group ="Concept") @Disabled public class ConceptVuforiaNavigation extends LinearOpMode { @@ -115,9 +115,9 @@ public class ConceptVuforiaNavigation extends LinearOpMode { * random data. As an example, here is a example of a fragment of a valid key: * ... yIgIzTqZ4mWjk9wd3cZO9T1axEqzuhxoGlfOOI2dRzKS4T0hQ8kT ... * Once you've obtained a license key, copy the string from the Vuforia web site - * and paste it in to your code onthe next line, between the double quotes. + * and paste it in to your code on the next line, between the double quotes. */ - parameters.vuforiaLicenseKey = "ATsODcD/////AAAAAVw2lR...d45oGpdljdOh5LuFB9nDNfckoxb8COxKSFX"; + parameters.vuforiaLicenseKey = " -- YOUR NEW VUFORIA KEY GOES HERE --- "; /* * We also indicate which camera on the RC that we wish to use. @@ -125,7 +125,11 @@ public class ConceptVuforiaNavigation extends LinearOpMode { * for a competition robot, the front camera might be more convenient. */ parameters.cameraDirection = VuforiaLocalizer.CameraDirection.BACK; - this.vuforia = ClassFactory.createVuforiaLocalizer(parameters); + + /** + * Instantiate the Vuforia engine + */ + vuforia = ClassFactory.getInstance().createVuforia(parameters); /** * Load the data sets that for the trackable objects we wish to track. These particular data diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVuforiaNavigationWebcam.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVuforiaNavigationWebcam.java new file mode 100644 index 00000000000..1b619f3dea5 --- /dev/null +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptVuforiaNavigationWebcam.java @@ -0,0 +1,461 @@ +/* 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.graphics.Bitmap; + +import com.qualcomm.robotcore.eventloop.opmode.TeleOp; +import com.qualcomm.robotcore.eventloop.opmode.Disabled; +import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode; +import com.qualcomm.robotcore.util.RobotLog; +import com.qualcomm.robotcore.util.ThreadPool; +import com.vuforia.Frame; + +import org.firstinspires.ftc.robotcore.external.ClassFactory; +import org.firstinspires.ftc.robotcore.external.function.Consumer; +import org.firstinspires.ftc.robotcore.external.function.Continuation; +import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName; +import org.firstinspires.ftc.robotcore.external.matrices.MatrixF; +import org.firstinspires.ftc.robotcore.external.matrices.OpenGLMatrix; +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.VuforiaLocalizer; +import org.firstinspires.ftc.robotcore.external.navigation.VuforiaTrackable; +import org.firstinspires.ftc.robotcore.external.navigation.VuforiaTrackableDefaultListener; +import org.firstinspires.ftc.robotcore.external.navigation.VuforiaTrackables; +import org.firstinspires.ftc.robotcore.internal.system.AppUtil; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +/** + * This 2016-2017 OpMode illustrates the basics of using the Vuforia localizer to determine + * positioning and orientation of robot on the FTC field. + * The code is structured as a LinearOpMode + * + * Vuforia uses the phone's camera to inspect it's surroundings, and attempt to locate target images. + * + * When images are located, Vuforia is able to determine the position and orientation of the + * image relative to the camera. This sample code than combines that information with a + * knowledge of where the target images are on the field, to determine the location of the camera. + * + * This example assumes a "diamond" field configuration where the red and blue alliance stations + * are adjacent on the corner of the field furthest from the audience. + * From the Audience perspective, the Red driver station is on the right. + * The two vision target are located on the two walls closest to the audience, facing in. + * The Stones are on the RED side of the field, and the Chips are on the Blue side. + * + * A final calculation then uses the location of the camera on the robot to determine the + * robot's location and orientation on the field. + * + * @see VuforiaLocalizer + * @see VuforiaTrackableDefaultListener + * see ftc_app/doc/tutorial/FTC_FieldCoordinateSystemDefinition.pdf + * + * 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. + * + * IMPORTANT: In order to use this OpMode, you need to obtain your own Vuforia license key as + * is explained below. + */ + +@TeleOp(name="Concept: Vuforia Nav Webcam", group ="Concept") +@Disabled +public class ConceptVuforiaNavigationWebcam extends LinearOpMode { + + public static final String TAG = "Vuforia Navigation Sample"; + + OpenGLMatrix lastLocation = null; + + /** + * @see #captureFrameToFile() + */ + int captureCounter = 0; + File captureDirectory = AppUtil.ROBOT_DATA_DIR; + + /** + * {@link #vuforia} is the variable we will use to store our instance of the Vuforia + * localization engine. + */ + VuforiaLocalizer vuforia; + + /** + * This is the webcam we are to use. As with other hardware devices such as motors and + * servos, this device is identified using the robot configuration tool in the FTC application. + */ + WebcamName webcamName; + + @Override public void runOpMode() { + + /* + * Retrieve the camera we are to use. + */ + webcamName = hardwareMap.get(WebcamName.class, "Webcam 1"); + + /* + * To start up Vuforia, tell it the view that we wish to use for camera monitor (on the RC phone); + * If no camera monitor is desired, use the parameterless constructor instead (commented out below). + */ + int cameraMonitorViewId = hardwareMap.appContext.getResources().getIdentifier("cameraMonitorViewId", "id", hardwareMap.appContext.getPackageName()); + VuforiaLocalizer.Parameters parameters = new VuforiaLocalizer.Parameters(cameraMonitorViewId); + + // OR... Do Not Activate the Camera Monitor View, to save power + // VuforiaLocalizer.Parameters parameters = new VuforiaLocalizer.Parameters(); + + /* + * IMPORTANT: You need to obtain your own license key to use Vuforia. The string below with which + * 'parameters.vuforiaLicenseKey' is initialized is for illustration only, and will not function. + * A Vuforia 'Development' license key, can be obtained free of charge from the Vuforia developer + * web site at https://developer.vuforia.com/license-manager. + * + * Vuforia license keys are always 380 characters long, and look as if they contain mostly + * random data. As an example, here is a example of a fragment of a valid key: + * ... yIgIzTqZ4mWjk9wd3cZO9T1axEqzuhxoGlfOOI2dRzKS4T0hQ8kT ... + * Once you've obtained a license key, copy the string from the Vuforia web site + * and paste it in to your code on the next line, between the double quotes. + */ + parameters.vuforiaLicenseKey = " -- YOUR NEW VUFORIA KEY GOES HERE --- "; + + /** + * We also indicate which camera on the RC we wish to use. + */ + parameters.cameraName = webcamName; + + /** + * Instantiate the Vuforia engine + */ + vuforia = ClassFactory.getInstance().createVuforia(parameters); + + /** + * Because this opmode processes frames in order to write them to a file, we tell Vuforia + * that we want to ensure that certain frame formats are available in the {@link Frame}s we + * see. + */ + vuforia.enableConvertFrameToBitmap(); + + /** @see #captureFrameToFile() */ + AppUtil.getInstance().ensureDirectoryExists(captureDirectory); + + + /** + * Load the data sets that for the trackable objects we wish to track. These particular data + * sets are stored in the 'assets' part of our application (you'll see them in the Android + * Studio 'Project' view over there on the left of the screen). You can make your own datasets + * with the Vuforia Target Manager: https://developer.vuforia.com/target-manager. PDFs for the + * example "StonesAndChips", datasets can be found in in this project in the + * documentation directory. + */ + VuforiaTrackables stonesAndChips = vuforia.loadTrackablesFromAsset("StonesAndChips"); + VuforiaTrackable redTarget = stonesAndChips.get(0); + redTarget.setName("RedTarget"); // Stones + + VuforiaTrackable blueTarget = stonesAndChips.get(1); + blueTarget.setName("BlueTarget"); // Chips + + /** For convenience, gather together all the trackable objects in one easily-iterable collection */ + List allTrackables = new ArrayList(); + allTrackables.addAll(stonesAndChips); + + /** + * We use units of mm here because that's the recommended units of measurement for the + * size values specified in the XML for the ImageTarget trackables in data sets. E.g.: + * + * You don't *have to* use mm here, but the units here and the units used in the XML + * target configuration files *must* correspond for the math to work out correctly. + */ + float mmPerInch = 25.4f; + float mmBotWidth = 18 * mmPerInch; // ... or whatever is right for your robot + float mmFTCFieldWidth = (12*12 - 2) * mmPerInch; // the FTC field is ~11'10" center-to-center of the glass panels + + /** + * In order for localization to work, we need to tell the system where each target we + * wish to use for navigation resides on the field, and we need to specify where on the robot + * the camera resides. These specifications are in the form of transformation matrices. + * Transformation matrices are a central, important concept in the math here involved in localization. + * See Transformation Matrix + * for detailed information. Commonly, you'll encounter transformation matrices as instances + * of the {@link OpenGLMatrix} class. + * + * For the most part, you don't need to understand the details of the math of how transformation + * matrices work inside (as fascinating as that is, truly). Just remember these key points: + *
    + * + *
  1. You can put two transformations together to produce a third that combines the effect of + * both of them. If, for example, you have a rotation transform R and a translation transform T, + * then the combined transformation matrix RT which does the rotation first and then the translation + * is given by {@code RT = T.multiplied(R)}. That is, the transforms are multiplied in the + * reverse of the chronological order in which they applied.
  2. + * + *
  3. A common way to create useful transforms is to use methods in the {@link OpenGLMatrix} + * class and the Orientation class. See, for example, {@link OpenGLMatrix#translation(float, + * float, float)}, {@link OpenGLMatrix#rotation(AngleUnit, float, float, float, float)}, and + * {@link Orientation#getRotationMatrix(AxesReference, AxesOrder, AngleUnit, float, float, float)}. + * Related methods in {@link OpenGLMatrix}, such as {@link OpenGLMatrix#rotated(AngleUnit, + * float, float, float, float)}, are syntactic shorthands for creating a new transform and + * then immediately multiplying the receiver by it, which can be convenient at times.
  4. + * + *
  5. If you want to break open the black box of a transformation matrix to understand + * what it's doing inside, use {@link MatrixF#getTranslation()} to fetch how much the + * transform will move you in x, y, and z, and use {@link Orientation#getOrientation(MatrixF, + * AxesReference, AxesOrder, AngleUnit)} to determine the rotational motion that the transform + * will impart. See {@link #format(OpenGLMatrix)} below for an example.
  6. + * + *
+ * + * This example places the "stones" image on the perimeter wall to the Left + * of the Red Driver station wall. Similar to the Red Beacon Location on the Res-Q + * + * This example places the "chips" image on the perimeter wall to the Right + * of the Blue Driver station. Similar to the Blue Beacon Location on the Res-Q + * + * See the doc folder of this project for a description of the Field Coordinate System + * conventions. + * + * Initially the target is conceptually lying at the origin of the Field Coordinate System + * (the center of the field), facing up. + * + * In this configuration, the target's coordinate system aligns with that of the field. + * + * In a real situation we'd also account for the vertical (Z) offset of the target, + * but for simplicity, we ignore that here; for a real robot, you'll want to fix that. + * + * To place the Stones Target on the Red Audience wall: + * - First we rotate it 90 around the field's X axis to flip it upright + * - Then we rotate it 90 around the field's Z access to face it away from the audience. + * - Finally, we translate it back along the X axis towards the red audience wall. + */ + OpenGLMatrix redTargetLocationOnField = OpenGLMatrix + /* Then we translate the target off to the RED WALL. Our translation here + is a negative translation in X.*/ + .translation(-mmFTCFieldWidth/2, 0, 0) + .multiplied(Orientation.getRotationMatrix( + /* First, in the fixed (field) coordinate system, we rotate 90deg in X, then 90 in Z */ + AxesReference.EXTRINSIC, AxesOrder.XZX, + AngleUnit.DEGREES, 90, 90, 0)); + redTarget.setLocationFtcFieldFromTarget(redTargetLocationOnField); + RobotLog.ii(TAG, "Red Target=%s", format(redTargetLocationOnField)); + + /* + * To place the Stones Target on the Blue Audience wall: + * - First we rotate it 90 around the field's X axis to flip it upright + * - Finally, we translate it along the Y axis towards the blue audience wall. + */ + OpenGLMatrix blueTargetLocationOnField = OpenGLMatrix + /* Then we translate the target off to the Blue Audience wall. + Our translation here is a positive translation in Y.*/ + .translation(0, mmFTCFieldWidth/2, 0) + .multiplied(Orientation.getRotationMatrix( + /* First, in the fixed (field) coordinate system, we rotate 90deg in X */ + AxesReference.EXTRINSIC, AxesOrder.XZX, + AngleUnit.DEGREES, 90, 0, 0)); + blueTarget.setLocationFtcFieldFromTarget(blueTargetLocationOnField); + RobotLog.ii(TAG, "Blue Target=%s", format(blueTargetLocationOnField)); + + /** + * We also need to tell Vuforia where the cameras are relative to the robot. + * + * Just as there is a Field Coordinate System, so too there is a Robot Coordinate System. + * The two share many similarities. The origin of the Robot Coordinate System is wherever + * you choose to make it on the robot, but typically you'd choose somewhere in the middle + * of the robot. From that origin, the Y axis is horizontal and positive out towards the + * "front" of the robot (however you choose "front" to be defined), the X axis is horizontal + * and positive out towards the "right" of the robot (i.e.: 90deg horizontally clockwise from + * the positive Y axis), and the Z axis is vertical towards the sky. + * + * Similarly, for each camera there is a Camera Coordinate System. The origin of a Camera + * Coordinate System lies in the middle of the sensor inside of the camera. The Z axis is + * positive coming out of the lens of the camera in a direction perpendicular to the plane + * of the sensor. When looking at the face of the lens of the camera (down the positive Z + * axis), the X axis is positive off to the right in the plane of the sensor, and the Y axis + * is positive out the top of the lens in the plane of the sensor at 90 horizontally + * counter clockwise from the X axis. + * + * Next, there is Phone Coordinate System (for robots that have phones, of course), though + * with the advent of Vuforia support for Webcams, this coordinate system is less significant + * than it was previously. The Phone Coordinate System is defined thusly: with the phone in + * flat front of you in portrait mode (i.e. as it is when running the robot controller app) + * and you are staring straight at the face of the phone, + * * X is positive heading off to your right, + * * Y is positive heading up through the top edge of the phone, and + * * Z is pointing out of the screen, toward you. + * The origin of the Phone Coordinate System is at the origin of the Camera Coordinate System + * of the front-facing camera on the phone. + * + * Finally, it is worth noting that trackable Vuforia Image Targets have their own + * coordinate system (see {@link VuforiaTrackable}. This is sometimes referred to as the + * Target Coordinate System. In keeping with the above, when looking at the target in its + * natural orientation, in the Target Coodinate System + * * X is positive heading off to your right, + * * Y is positive heading up through the top edge of the target, and + * * Z is pointing out of the target, toward you. + * + * One can observe that the Camera Coordinate System of the front-facing camera on a phone + * coincides with the Phone Coordinate System. Further, when a phone is placed on its back + * at the origin of the Robot Coordinate System and aligned appropriately, those coordinate + * systems also coincide with the Robot Coordinate System. Got it? + * + * In this example here, we're going to assume that we put the camera on the right side + * of the robot (facing outwards, of course). To determine the transformation matrix that + * describes that location, first consider the camera as lying on its back at the origin + * of the Robot Coordinate System such that the Camera Coordinate System and Robot Coordinate + * System coincide. Then the transformation we need is + * * first a rotation of the camera by +90deg along the robot X axis, + * * then a rotation of the camera by +90deg along the robot Z axis, and + * * finally a translation of the camera to the side of the robot. + * + * When determining whether a rotation is positive or negative, consider yourself as looking + * down the (positive) axis of rotation from the positive towards the origin. Positive rotations + * are then CCW, and negative rotations CW. An example: consider looking down the positive Z + * axis towards the origin. A positive rotation about Z (ie: a rotation parallel to the the X-Y + * plane) is then CCW, as one would normally expect from the usual classic 2D geometry. + */ + + OpenGLMatrix robotFromCamera = OpenGLMatrix + .translation(mmBotWidth/2,0,0) + .multiplied(Orientation.getRotationMatrix( + AxesReference.EXTRINSIC, AxesOrder.XZY, + AngleUnit.DEGREES, 90, 90, 0)); + RobotLog.ii(TAG, "camera=%s", format(robotFromCamera)); + + /** + * Let the trackable listeners we care about know where the camera is. We know that each + * listener is a {@link VuforiaTrackableDefaultListener} and can so safely cast because + * we have not ourselves installed a listener of a different type. + */ + ((VuforiaTrackableDefaultListener)redTarget.getListener()).setCameraLocationOnRobot(parameters.cameraName, robotFromCamera); + ((VuforiaTrackableDefaultListener)blueTarget.getListener()).setCameraLocationOnRobot(parameters.cameraName, robotFromCamera); + + /** + * A brief tutorial: here's how all the math is going to work: + * + * C = robotFromCamera maps camera coords -> robot coords + * P = tracker.getPose() maps image target coords -> camera coords + * L = redTargetLocationOnField maps image target coords -> field coords + * + * So + * + * C.inverted() maps robot coords -> camera coords + * P.inverted() maps camera coords -> imageTarget coords + * + * Putting that all together, + * + * L x P.inverted() x C.inverted() maps robot coords to field coords. + * + * @see VuforiaTrackableDefaultListener#getRobotLocation() + */ + + /** Wait for the game to begin */ + telemetry.addData(">", "Press Play to start tracking"); + telemetry.update(); + waitForStart(); + + /** Start tracking the data sets we care about. */ + stonesAndChips.activate(); + + boolean buttonPressed = false; + while (opModeIsActive()) { + + if (gamepad1.a && !buttonPressed) { + captureFrameToFile(); + } + buttonPressed = gamepad1.a; + + for (VuforiaTrackable trackable : allTrackables) { + /** + * getUpdatedRobotLocation() will return null if no new information is available since + * the last time that call was made, or if the trackable is not currently visible. + * getRobotLocation() will return null if the trackable is not currently visible. + */ + telemetry.addData(trackable.getName(), ((VuforiaTrackableDefaultListener)trackable.getListener()).isVisible() ? "Visible" : "Not Visible"); // + + OpenGLMatrix robotLocationTransform = ((VuforiaTrackableDefaultListener)trackable.getListener()).getUpdatedRobotLocation(); + if (robotLocationTransform != null) { + lastLocation = robotLocationTransform; + } + } + /** + * Provide feedback as to where the robot was last located (if we know). + */ + if (lastLocation != null) { + // RobotLog.vv(TAG, "robot=%s", format(lastLocation)); + telemetry.addData("Pos", format(lastLocation)); + } else { + telemetry.addData("Pos", "Unknown"); + } + telemetry.update(); + } + } + + /** + * A simple utility that extracts positioning information from a transformation matrix + * and formats it in a form palatable to a human being. + */ + String format(OpenGLMatrix transformationMatrix) { + return transformationMatrix.formatAsTransform(); + } + + /** + * Sample one frame from the Vuforia stream and write it to a .PNG image file on the robot + * controller in the /sdcard/FIRST/data directory. The images can be downloaded using Android + * Studio's Device File Explorer, ADB, or the Media Transfer Protocol (MTP) integration into + * Windows Explorer, among other means. The images can be useful during robot design and calibration + * in order to get a sense of what the camera is actually seeing and so assist in camera + * aiming and alignment. + */ + void captureFrameToFile() { + vuforia.getFrameOnce(Continuation.create(ThreadPool.getDefault(), new Consumer() + { + @Override public void accept(Frame frame) + { + Bitmap bitmap = vuforia.convertFrameToBitmap(frame); + if (bitmap != null) { + File file = new File(captureDirectory, String.format(Locale.getDefault(), "VuforiaFrame-%d.png", captureCounter++)); + try { + FileOutputStream outputStream = new FileOutputStream(file); + try { + bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream); + } finally { + outputStream.close(); + telemetry.log().add("captured %s", file.getName()); + } + } catch (IOException e) { + RobotLog.ee(TAG, e, "exception in captureFrameToFile()"); + } + } + } + })); + } +} diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SampleRevBlinkinLedDriver.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SampleRevBlinkinLedDriver.java new file mode 100644 index 00000000000..337b7032152 --- /dev/null +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SampleRevBlinkinLedDriver.java @@ -0,0 +1,164 @@ +/* + * 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; + +/* + * Display patterns of a 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/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorAdafruitRGB.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorAdafruitRGB.java index f3f52764cff..6a94e25fb6a 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorAdafruitRGB.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorAdafruitRGB.java @@ -33,9 +33,9 @@ import android.graphics.Color; import android.view.View; -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.eventloop.opmode.TeleOp; import com.qualcomm.robotcore.hardware.ColorSensor; import com.qualcomm.robotcore.hardware.DeviceInterfaceModule; import com.qualcomm.robotcore.hardware.DigitalChannel; @@ -67,7 +67,7 @@ * 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 = "Sensor: AdafruitRGB", group = "Sensor") +@TeleOp(name = "Sensor: AdafruitRGB", group = "Sensor") @Disabled // Comment this out to add to the opmode list public class SensorAdafruitRGB extends LinearOpMode { 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 b52d6583c4c..9102a108d87 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 @@ -31,9 +31,9 @@ import com.qualcomm.hardware.bosch.BNO055IMU; import com.qualcomm.hardware.bosch.JustLoggingAccelerationIntegrator; -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.eventloop.opmode.TeleOp; import org.firstinspires.ftc.robotcore.external.Func; import org.firstinspires.ftc.robotcore.external.navigation.Acceleration; @@ -54,7 +54,7 @@ * * @see Adafruit IMU */ -@Autonomous(name = "Sensor: BNO055 IMU", group = "Sensor") +@TeleOp(name = "Sensor: BNO055 IMU", group = "Sensor") @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/SensorDigitalTouch.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorDigitalTouch.java index 8da2afb774e..6bb648056bb 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorDigitalTouch.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorDigitalTouch.java @@ -29,9 +29,9 @@ 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.eventloop.opmode.TeleOp; import com.qualcomm.robotcore.hardware.DigitalChannel; /* @@ -43,7 +43,7 @@ * 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 = "Sensor: Digital touch", group = "Sensor") +@TeleOp(name = "Sensor: Digital touch", group = "Sensor") @Disabled public class SensorDigitalTouch extends LinearOpMode { /** diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorHTColor.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorHTColor.java index e0de829b3b4..e872273c27a 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorHTColor.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorHTColor.java @@ -33,9 +33,9 @@ import android.graphics.Color; import android.view.View; -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.eventloop.opmode.TeleOp; import com.qualcomm.robotcore.hardware.ColorSensor; /* @@ -49,7 +49,7 @@ * 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 = "Sensor: HT color", group = "Sensor") +@TeleOp(name = "Sensor: HT color", group = "Sensor") @Disabled public class SensorHTColor extends LinearOpMode { diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorHTGyro.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorHTGyro.java index d4ad94c7073..0e853ca6b08 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorHTGyro.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorHTGyro.java @@ -30,9 +30,9 @@ package org.firstinspires.ftc.robotcontroller.external.samples; import com.qualcomm.hardware.hitechnic.HiTechnicNxtGyroSensor; -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.eventloop.opmode.TeleOp; import com.qualcomm.robotcore.hardware.Gyroscope; import com.qualcomm.robotcore.hardware.IntegratingGyroscope; @@ -45,7 +45,7 @@ * 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 = "Sensor: HT Gyro", group = "Sensor") +@TeleOp(name = "Sensor: HT Gyro", group = "Sensor") @Disabled public class SensorHTGyro extends LinearOpMode { diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorKLNavxMicro.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorKLNavxMicro.java index 40e4a94e5ff..583f52569ad 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorKLNavxMicro.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorKLNavxMicro.java @@ -30,9 +30,9 @@ package org.firstinspires.ftc.robotcontroller.external.samples; import com.qualcomm.hardware.kauailabs.NavxMicroNavigationSensor; -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.eventloop.opmode.TeleOp; import com.qualcomm.robotcore.hardware.Gyroscope; import com.qualcomm.robotcore.hardware.IntegratingGyroscope; import com.qualcomm.robotcore.util.ElapsedTime; @@ -50,7 +50,7 @@ * 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 = "Sensor: KL navX Micro", group = "Sensor") +@TeleOp(name = "Sensor: KL navX Micro", group = "Sensor") @Disabled public class SensorKLNavxMicro extends LinearOpMode { diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRCompass.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRCompass.java index 90ab7047c1b..583ac1aab3e 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRCompass.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRCompass.java @@ -30,9 +30,9 @@ package org.firstinspires.ftc.robotcontroller.external.samples; import com.qualcomm.hardware.modernrobotics.ModernRoboticsI2cCompassSensor; -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.eventloop.opmode.TeleOp; import com.qualcomm.robotcore.hardware.CompassSensor; import com.qualcomm.robotcore.util.ElapsedTime; @@ -49,7 +49,7 @@ * * @see MR Compass Sensor */ -@Autonomous(name = "Sensor: MR compass", group = "Sensor") +@TeleOp(name = "Sensor: MR compass", group = "Sensor") @Disabled // comment out or remove this line to enable this opmode public class SensorMRCompass extends LinearOpMode { diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRRangeSensor.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRRangeSensor.java index 5acbd10e56b..d7de1fff0e8 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRRangeSensor.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRRangeSensor.java @@ -30,9 +30,9 @@ package org.firstinspires.ftc.robotcontroller.external.samples; import com.qualcomm.hardware.modernrobotics.ModernRoboticsI2cRangeSensor; -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.eventloop.opmode.TeleOp; import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit; @@ -47,7 +47,7 @@ * * @see MR Range Sensor */ -@Autonomous(name = "Sensor: MR range sensor", group = "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 { diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorREV2mDistance.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorREV2mDistance.java new file mode 100644 index 00000000000..880bd84523b --- /dev/null +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorREV2mDistance.java @@ -0,0 +1,89 @@ +/* +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 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; + +import com.qualcomm.hardware.rev.Rev2mDistanceSensor; +import com.qualcomm.robotcore.eventloop.opmode.TeleOp; +import com.qualcomm.robotcore.eventloop.opmode.Disabled; +import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode; +import com.qualcomm.robotcore.hardware.DistanceSensor; + +import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit; + +/** + * {@link SensorREV2mDistance} illustrates how to use the REV Robotics + * Time-of-Flight Range Sensor. + * + * The op mode 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 REV Robotics Web Page + */ +@TeleOp(name = "Sensor: REV2mDistance", group = "Sensor") +@Disabled +public class SensorREV2mDistance extends LinearOpMode { + + private DistanceSensor sensorRange; + + @Override + public void runOpMode() { + // you can use this as a regular DistanceSensor. + sensorRange = hardwareMap.get(DistanceSensor.class, "sensor_range"); + + // you can also cast this to a Rev2mDistanceSensor if you want to use added + // methods associated with the Rev2mDistanceSensor class. + Rev2mDistanceSensor sensorTimeOfFlight = (Rev2mDistanceSensor)sensorRange; + + telemetry.addData(">>", "Press start to continue"); + telemetry.update(); + + waitForStart(); + while(opModeIsActive()) { + // generic DistanceSensor methods. + telemetry.addData("deviceName",sensorRange.getDeviceName() ); + telemetry.addData("range", String.format("%.01f mm", sensorRange.getDistance(DistanceUnit.MM))); + telemetry.addData("range", String.format("%.01f cm", sensorRange.getDistance(DistanceUnit.CM))); + telemetry.addData("range", String.format("%.01f m", sensorRange.getDistance(DistanceUnit.METER))); + telemetry.addData("range", String.format("%.01f in", sensorRange.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(); + } + } + +} \ No newline at end of file diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorREVColorDistance.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorREVColorDistance.java index 11a8880f9e7..37910ca97b5 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorREVColorDistance.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorREVColorDistance.java @@ -33,9 +33,9 @@ import android.graphics.Color; import android.view.View; -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.eventloop.opmode.TeleOp; import com.qualcomm.robotcore.hardware.ColorSensor; import com.qualcomm.robotcore.hardware.DistanceSensor; @@ -52,7 +52,7 @@ * 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 = "Sensor: REVColorDistance", group = "Sensor") +@TeleOp(name = "Sensor: REVColorDistance", group = "Sensor") @Disabled // Comment this out to add to the opmode list public class SensorREVColorDistance extends LinearOpMode { diff --git a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/FtcRobotControllerActivity.java b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/FtcRobotControllerActivity.java index 4ec32fa4315..d5d6872efda 100644 --- a/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/FtcRobotControllerActivity.java +++ b/FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/FtcRobotControllerActivity.java @@ -43,10 +43,13 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbManager; import android.net.wifi.WifiManager; +import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.preference.PreferenceManager; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.annotation.StringRes; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; @@ -54,6 +57,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE import android.webkit.WebView; import android.widget.ImageButton; import android.widget.LinearLayout; +import android.widget.PopupMenu; import android.widget.TextView; import com.google.blocks.ftcrobotcontroller.BlocksActivity; @@ -61,8 +65,8 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE import com.google.blocks.ftcrobotcontroller.ProgrammingModeControllerImpl; import com.google.blocks.ftcrobotcontroller.ProgrammingWebHandlers; import com.google.blocks.ftcrobotcontroller.runtime.BlocksOpMode; -import com.qualcomm.ftccommon.AboutActivity; 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; @@ -84,20 +88,26 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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.util.Device; import com.qualcomm.robotcore.util.Dimmer; import com.qualcomm.robotcore.util.ImmersiveMode; import com.qualcomm.robotcore.util.RobotLog; +import com.qualcomm.robotcore.wifi.NetworkConnection; import com.qualcomm.robotcore.wifi.NetworkConnectionFactory; import com.qualcomm.robotcore.wifi.NetworkType; -import com.qualcomm.robotcore.wifi.WifiDirectAssistant; import org.firstinspires.ftc.ftccommon.external.SoundPlayingRobotMonitor; import org.firstinspires.ftc.ftccommon.internal.FtcRobotControllerWatchdogService; import org.firstinspires.ftc.ftccommon.internal.ProgramAndManageActivity; +import org.firstinspires.ftc.robotcore.external.navigation.MotionDetection; import org.firstinspires.ftc.robotcore.internal.hardware.DragonboardLynxDragonboardIsPresentPin; import org.firstinspires.ftc.robotcore.internal.network.DeviceNameManager; +import org.firstinspires.ftc.robotcore.internal.network.DeviceNameManagerFactory; +import org.firstinspires.ftc.robotcore.internal.network.WifiDirectDeviceNameManager; import org.firstinspires.ftc.robotcore.internal.network.PreferenceRemoterRC; import org.firstinspires.ftc.robotcore.internal.network.StartResult; +import org.firstinspires.ftc.robotcore.internal.network.WifiMuteEvent; +import org.firstinspires.ftc.robotcore.internal.network.WifiMuteStateMachine; import org.firstinspires.ftc.robotcore.internal.system.AppUtil; import org.firstinspires.ftc.robotcore.internal.system.Assert; import org.firstinspires.ftc.robotcore.internal.system.PreferencesHelper; @@ -130,8 +140,8 @@ public class FtcRobotControllerActivity extends Activity protected UpdateUI.Callback callback; protected Context context; protected Utility utility; - protected StartResult deviceNameManagerStartResult = new StartResult(); protected StartResult prefRemoterStartResult = new StartResult(); + protected StartResult deviceNameStartResult = new StartResult(); protected PreferencesHelper preferencesHelper; protected final SharedPreferencesListener sharedPreferencesListener = new SharedPreferencesListener(); @@ -154,6 +164,9 @@ public class FtcRobotControllerActivity extends Activity protected FtcEventLoop eventLoop; protected Queue receivedUsbAttachmentNotifications; + protected WifiMuteStateMachine wifiMuteStateMachine; + protected MotionDetection motionDetection; + protected class RobotRestarter implements Restarter { public void requestRestart() { @@ -220,6 +233,8 @@ protected void onCreate(Bundle savedInstanceState) { 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()); Assert.assertTrue(FtcRobotControllerWatchdogService.isFtcRobotControllerActivity(AppUtil.getInstance().getRootActivity())); Assert.assertTrue(AppUtil.getInstance().isRobotController()); @@ -240,7 +255,9 @@ protected void onCreate(Bundle savedInstanceState) { context = this; utility = new Utility(this); - DeviceNameManager.getInstance().start(deviceNameManagerStartResult); + + DeviceNameManagerFactory.getInstance().start(deviceNameStartResult); + PreferenceRemoterRC.getInstance().start(prefRemoterStartResult); receivedUsbAttachmentNotifications = new ConcurrentLinkedQueue(); @@ -257,7 +274,15 @@ protected void onCreate(Bundle savedInstanceState) { buttonMenu.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - AppUtil.getInstance().openOptionsMenuFor(FtcRobotControllerActivity.this); + 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); + popupMenu.show(); } }); @@ -300,11 +325,17 @@ public void onClick(View v) { hittingMenuButtonBrightensScreen(); wifiLock.acquire(); - callback.networkConnectionUpdate(WifiDirectAssistant.Event.DISCONNECTED); + callback.networkConnectionUpdate(NetworkConnection.NetworkEvent.DISCONNECTED); readNetworkType(); ServiceController.startService(FtcRobotControllerWatchdogService.class); bindToService(); logPackageVersions(); + logDeviceSerialNumber(); + RobotLog.logDeviceInfo(); + + if (preferencesHelper.readBoolean(getString(R.string.pref_wifi_automute), false)) { + initWifiMute(true); + } } protected UpdateUI createUpdateUI() { @@ -374,8 +405,8 @@ protected void onDestroy() { shutdownRobot(); // Ensure the robot is put away to bed if (callback != null) callback.close(); - PreferenceRemoterRC.getInstance().start(prefRemoterStartResult); - DeviceNameManager.getInstance().stop(deviceNameManagerStartResult); + PreferenceRemoterRC.getInstance().stop(prefRemoterStartResult); + DeviceNameManagerFactory.getInstance().stop(deviceNameStartResult); unbindFromService(); // If the app manually (?) is stopped, then we don't need the auto-starting function (?) @@ -408,6 +439,10 @@ protected void logPackageVersions() { RobotLog.logBuildConfig(org.firstinspires.inspection.BuildConfig.class); } + protected void logDeviceSerialNumber() { + RobotLog.ii(TAG, "410c serial number: " + Build.SERIAL); + } + protected void readNetworkType() { // The code here used to defer to the value found in a configuration file @@ -418,10 +453,17 @@ protected void readNetworkType() { // Moreover, the non-Wifi-Direct networking is end-of-life, so the simplest and most robust // (e.g.: no one can screw things up by messing with the contents of the config file) fix is // to do away with configuration file entirely. - networkType = NetworkType.WIFIDIRECT; + // + // Control hubs are always running the access point model. Everything else, for the time + // being always runs the wifi 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_network_connection_type), networkType.toString()); + preferencesHelper.writeStringPrefIfDifferent(context.getString(R.string.pref_pairing_kind), networkType.toString()); } @Override @@ -498,8 +540,7 @@ else if (id == R.id.action_settings) { return true; } else if (id == R.id.action_about) { - Intent intent = new Intent(AppUtil.getDefContext(), AboutActivity.class); - intent.putExtra(LaunchActivityConstantsList.ABOUT_ACTIVITY_CONNECTION_TYPE, networkType); + Intent intent = new Intent(AppUtil.getDefContext(), FtcAboutActivity.class); startActivity(intent); return true; } @@ -555,14 +596,20 @@ private void updateUIAndRequestRobotSetup() { if (controllerService != null) { callback.networkConnectionUpdate(controllerService.getNetworkConnectionStatus()); callback.updateRobotStatus(controllerService.getRobotStatus()); - requestRobotSetup(); + // 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() { + private void requestRobotSetup(@Nullable Runnable runOnComplete) { if (controllerService == null) return; - HardwareFactory factory; RobotConfigFile file = cfgFileMgr.getActiveConfigAndUpdateUI(); HardwareFactory hardwareFactory = new HardwareFactory(context); try { @@ -572,14 +619,13 @@ private void requestRobotSetup() { hardwareFactory.setXmlPullParser(file.getXml()); cfgFileMgr.setActiveConfigAndUpdateUI(false, file); } - factory = hardwareFactory; OpModeRegister userOpModeRegister = createOpModeRegister(); - eventLoop = new FtcEventLoop(factory, userOpModeRegister, callback, this, programmingModeController); - FtcEventLoopIdle idleLoop = new FtcEventLoopIdle(factory, userOpModeRegister, callback, this, programmingModeController); + eventLoop = new FtcEventLoop(hardwareFactory, userOpModeRegister, callback, this, programmingModeController); + FtcEventLoopIdle idleLoop = new FtcEventLoopIdle(hardwareFactory, userOpModeRegister, callback, this, programmingModeController); controllerService.setCallback(callback); - controllerService.setupRobot(eventLoop, idleLoop); + controllerService.setupRobot(eventLoop, idleLoop, runOnComplete); passReceivedUsbAttachmentsToEventLoop(); } @@ -595,10 +641,18 @@ private void shutdownRobot() { private void requestRobotRestart() { AppUtil.getInstance().showToast(UILocation.BOTH, AppUtil.getDefContext().getString(R.string.toastRestartingRobot)); // + RobotLog.clearGlobalErrorMsg(); + RobotLog.clearGlobalWarningMsg(); shutdownRobot(); - requestRobotSetup(); - // - AppUtil.getInstance().showToast(UILocation.BOTH, AppUtil.getDefContext().getString(R.string.toastRestartRobotComplete)); + 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)); } protected void hittingMenuButtonBrightensScreen() { @@ -619,7 +673,44 @@ protected class SharedPreferencesListener implements SharedPreferences.OnSharedP @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/FtcRobotController/src/main/res/xml/app_settings.xml b/FtcRobotController/src/main/res/xml/app_settings.xml index adc3223afe8..58d3aa9c70a 100644 --- a/FtcRobotController/src/main/res/xml/app_settings.xml +++ b/FtcRobotController/src/main/res/xml/app_settings.xml @@ -64,7 +64,7 @@ See https://developer.android.com/guide/topics/ui/settings.html diff --git a/FtcRobotController/src/main/res/xml/device_filter.xml b/FtcRobotController/src/main/res/xml/device_filter.xml index 6f728198bf8..7677dad219d 100644 --- a/FtcRobotController/src/main/res/xml/device_filter.xml +++ b/FtcRobotController/src/main/res/xml/device_filter.xml @@ -31,8 +31,20 @@ 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. --> + + + + + + + + diff --git a/README.md b/README.md index 46d46f4d5e4..1cfd09f9ebb 100644 --- a/README.md +++ b/README.md @@ -41,15 +41,114 @@ For technical questions regarding the SDK, please visit the FTC Technology forum       http://ftcforum.usfirst.org/forumdisplay.php?156-FTC-Technology - ************************************************************************************** # Release Information ************************************************************************************** -Version 3.7 (built on 18.03.12) +Version 4.0 (released on 18.09.12) Changes include: - * Interim fix to allow FTC apps to run on Android Nougat (7.x) devices. + * Initial support for UVC compatible cameras + - If UVC camera has a unique serial number, RC will detect and enumerate by serial number. + - If UVC camera lacks a unique serial number, RC will only support one camera of that type connected. + - Calibration settings for a few cameras are included (see TeamCode/src/main/res/xml/teamwebcamcalibrations.xml for details). + - User can upload calibration files from Program and Manage web interface. + - UVC cameras seem to draw a fair amount of electrical current from the USB bus. + + This does not appear to present any problems for the REV Robotics Control Hub. + + This does seem to create stability problems when using some cameras with an Android phone-based Robot Controller. + + FTC Tech Team is investigating options to mitigate this issue with the phone-based Robot Controllers. + - Updated sample Vuforia Navigation and VuMark Op Modes to demonstrate how to use an internal phone-based camera and an external UVC webcam. + + * Support for improved motor control. + - REV Robotics Expansion Hub firmware 1.8 and greater will support a feed forward mechanism for closed loop motor control. + - FTC SDK has been modified to support PIDF coefficients (proportional, integral, derivative, and feed forward). + - FTC Blocks development tool modified to include PIDF programming blocks. + - Deprecated older PID-related methods and variables. + - REV's 1.8.x PIDF-related changes provide a more linear and accurate way to control a motor. + + * Wireless + - Added 5GHz support for wireless channel changing for those devices that support it. + + Tested with Moto G5 and E4 phones. + + Also tested with other (currently non-approved) phones such as Samsung Galaxy S8. + +* Improved Expansion Hub firmware update support in Robot Controller app + - Changes to make the system more robust during the firmware update process (when performed through Robot Controller app). + - User no longer has to disconnect a downstream daisy-chained Expansion Hub when updating an Expansion Hub's firmware. + + If user is updating an Expansion Hub's firmware through a USB connection, he/she does not have to disconnect RS485 connection to other Expansion Hubs. + + The user still must use a USB connection to update an Expansion Hub's firmware. + + The user cannot update the Expansion Hub firmware for a downstream device that is daisy chained through an RS485 connection. + - If an Expansion Hub accidentally gets "bricked" the Robot Controller app is now more likely to recognize the Hub when it scans the USB bus. + + Robot Controller app should be able to detect an Expansion Hub, even if it accidentally was bricked in a previous update attempt. + + Robot Controller app should be able to install the firmware onto the Hub, even if if accidentally was bricked in a previous update attempt. + + * Resiliency + - FTC software can detect and enable an FTDI reset feature that is available with REV Robotics v1.8 Expansion Hub firmware and greater. + + When enabled, the Expansion Hub can detect if it hasn't communicated with the Robot Controller over the FTDI (USB) connection. + + If the Hub hasn't heard from the Robot Controller in a while, it will reset the FTDI connection. + + This action helps system recover from some ESD-induced disruptions. + - Various fixes to improve reliability of FTC software. + + * Blocks + - Fixed errors with string and list indices in blocks export to java. + - Support for USB connected UVC webcams. + - Refactored optimized Blocks Vuforia code to support Rover Ruckus image targets. + - Added programming blocks to support PIDF (proportional, integral, derivative and feed forward) motor control. + - Added formatting options (under Telemetry and Miscellaneous categories) so user can set how many decimal places to display a numerical value. + - Support to play audio files (which are uploaded through Blocks web interface) on Driver Station in addition to the Robot Controller. + - Fixed bug with Download Image of Blocks feature. + - Support for REV Robotics Blinkin LED Controller. + - Support for REV Robotics 2m Distance Sensor. + - Added support for a REV Touch Sensor (no longer have to configure as a generic digital device). + - Added blocks for DcMotorEx methods. + + These are enhanced methods that you can use when supported by the motor controller hardware. + + The REV Robotics Expansion Hub supports these enhanced methods. + + Enhanced methods include methods to get/set motor velocity (in encoder pulses per second), get/set PIDF coefficients, etc.. + + * Modest Improvements in Logging + - Decrease frequency of battery checker voltage statements. + - Removed non-FTC related log statements (wherever possible). + - Introduced a "Match Logging" feature. + + Under "Settings" a user can enable/disable this feature (it's disabled by default). + + If enabled, user provides a "Match Number" through the Driver Station user interface (top of the screen). + * The Match Number is used to create a log file specifically with log statements from that particular Op Mode run. + * Match log files are stored in /sdcard/FIRST/matlogs on the Robot Controller. + * Once an op mode run is complete, the Match Number is cleared. + * This is a convenient way to create a separate match log with statements only related to a specific op mode run. + + * New Devices + - Support for REV Robotics Blinkin LED Controller. + - Support for REV Robotics 2m Distance Sensor. + - Added configuration option for REV 20:1 HD Hex Motor. + - Added support for a REV Touch Sensor (no longer have to configure as a generic digital device). + + * Miscellaneous + - Fixed some errors in the definitions for acceleration and velocity in our javadoc documentation. + - Added ability to play audio files on Driver Station + - When user is configuring an Expansion Hub, the LED on the Expansion Hub will change blink pattern (purple-cyan) to indicate which Hub is currently being configured. + - Renamed I2cSensorType to I2cDeviceType. + - Added an external sample Op Mode that demonstrates localization using 2018-2019 (Rover Ruckus presented by QualComm) Vuforia targets. + - Added an external sample Op Mode that demonstrates how to use the REV Robotics 2m Laser Distance Sensor. + - Added an external sample Op Mode that demonstrates how to use the REV Robotics Blinkin LED Controller. + - Re-categorized external Java sample Op Modes to "TeleOp" instead of "Autonomous". + +Known issues: + * Initial support for UVC compatible cameras + - UVC cameras seem to draw significant amount of current from the USB bus. + + This does not appear to present any problems for the REV Robotics Control Hub. + + This does seem to create stability problems when using some cameras with an Android phone-based Robot Controller. + + FTC Tech Team is investigating options to mitigate this issue with the phone-based Robot Controllers. + - There might be a possible deadlock which causes the RC to become unresponsive when using a UVC webcam with a Nougat Android Robot Controller. + + * Wireless + - When user selects a wireless channel, this channel does not necessarily persist if the phone is power cycled. + + Tech Team is hoping to eventually address this issue in a future release. + + Issue has been present since apps were introduced (i.e., it is not new with the v4.0 release). + - Wireless channel is not currently displayed for WiFi Direct connections. + + * Miscellaneous + - The blink indication feature that shows which Expansion Hub is currently being configured does not work for a newly created configuration file. + + User has to first save a newly created configuration file and then close and re-edit the file in order for blink indicator to work. + ************************************************************************************** # Release Information diff --git a/TeamCode/build.release.gradle b/TeamCode/build.release.gradle index 17567abc8cf..8a645d1b6fc 100644 --- a/TeamCode/build.release.gradle +++ b/TeamCode/build.release.gradle @@ -1,8 +1,7 @@ dependencies { - compile project(':FtcRobotController') - compile (name: 'RobotCore-release', ext: 'aar') - compile (name: 'Hardware-release', ext: 'aar') - compile (name: 'FtcCommon-release', ext: 'aar') - compile (name:'Analytics-release', ext:'aar') - compile (name:'WirelessP2p-release', ext:'aar') + implementation project(':FtcRobotController') + implementation (name: 'RobotCore-release', ext: 'aar') + implementation (name: 'Hardware-release', ext: 'aar') + implementation (name: 'FtcCommon-release', ext: 'aar') + implementation (name:'WirelessP2p-release', ext:'aar') } diff --git a/TeamCode/src/main/res/xml/teamwebcamcalibrations.xml b/TeamCode/src/main/res/xml/teamwebcamcalibrations.xml new file mode 100644 index 00000000000..e2819d297d5 --- /dev/null +++ b/TeamCode/src/main/res/xml/teamwebcamcalibrations.xml @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build.common.gradle b/build.common.gradle index 7972001e976..9930f2a63e5 100644 --- a/build.common.gradle +++ b/build.common.gradle @@ -22,7 +22,6 @@ apply plugin: 'com.android.application' android { compileSdkVersion 23 - buildToolsVersion '25.0.3' signingConfigs { debug { @@ -68,6 +67,7 @@ android { } // Advanced user code might just want to use Vuforia directly, so we set up the libs as needed + // http://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.BuildType.html buildTypes { release { // Disable debugging for release versions so it can be uploaded to Google Play. @@ -78,6 +78,8 @@ android { } debug { debuggable true + jniDebuggable true + renderscriptDebuggable true ndk { abiFilters "armeabi-v7a" } diff --git a/build.gradle b/build.gradle index a267db58fc6..b20f6398825 100644 --- a/build.gradle +++ b/build.gradle @@ -5,10 +5,11 @@ */ buildscript { repositories { + google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.3' + classpath 'com.android.tools.build:gradle:3.1.3' } } diff --git a/doc/apk/FtcDriverStation-release.apk b/doc/apk/FtcDriverStation-release.apk index 8ae2c912716..747ab82446a 100644 Binary files a/doc/apk/FtcDriverStation-release.apk and b/doc/apk/FtcDriverStation-release.apk differ diff --git a/doc/apk/FtcRobotController-release.apk b/doc/apk/FtcRobotController-release.apk index 8926d724c41..cd05c21c153 100644 Binary files a/doc/apk/FtcRobotController-release.apk and b/doc/apk/FtcRobotController-release.apk differ diff --git a/doc/javadoc/allclasses-frame.html b/doc/javadoc/allclasses-frame.html index eb75ffd67d0..adcebdaac12 100644 --- a/doc/javadoc/allclasses-frame.html +++ b/doc/javadoc/allclasses-frame.html @@ -11,8 +11,6 @@

All Classes

+ + + +
    +
  • +

    handleCommandRequestAboutInfo

    +
    protected void handleCommandRequestAboutInfo(Command command)
    +
  • +
-
    +
    • handleCommandDisconnectWifiDirect

      protected void handleCommandDisconnectWifiDirect()
    + + + +
      +
    • +

      handleCommandVisuallyIdentify

      +
      protected CallbackResult handleCommandVisuallyIdentify(Command command)
      +
    • +
diff --git a/doc/javadoc/com/qualcomm/ftccommon/FtcEventLoopHandler.html b/doc/javadoc/com/qualcomm/ftccommon/FtcEventLoopHandler.html index 8dc794bd8bb..c00e0ac3bfd 100644 --- a/doc/javadoc/com/qualcomm/ftccommon/FtcEventLoopHandler.html +++ b/doc/javadoc/com/qualcomm/ftccommon/FtcEventLoopHandler.html @@ -17,8 +17,8 @@ catch(err) { } //--> -var methods = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10,"i10":10,"i11":10,"i12":10,"i13":10,"i14":10,"i15":10,"i16":10}; -var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]}; +var methods = {"i0":10,"i1":9,"i2":10,"i3":9,"i4":9,"i5":9,"i6":10,"i7":10,"i8":10,"i9":10,"i10":10,"i11":10,"i12":10,"i13":10,"i14":10,"i15":10,"i16":10,"i17":10,"i18":10}; +var tabs = {65535:["t0","All Methods"],1:["t1","Static Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]}; var altColor = "altColor"; var rowColor = "rowColor"; var tableTab = "tableTab"; @@ -132,21 +132,33 @@

Field Summary

callback  +protected static boolean +DEBUG  + + protected EventLoopManager eventLoopManager  - + protected HardwareFactory hardwareFactory  + +protected HardwareMap +hardwareMap +
the actual hardware map seen by the user
+ + protected HardwareMap -hardwareMap  +hardwareMapExtra +
the hardware map in which we keep any extra devices (ones not used by the user) we need to instantiate
+ static java.lang.String NO_VOLTAGE_SENSOR -
This string is sent in the robot battery telemetry payload to indicate +
This string is sent in the robot battery telemetry payload to identify that no voltage sensor is available on the robot.
@@ -235,7 +247,7 @@

Constructor Summary

Method Summary

- + @@ -245,50 +257,63 @@

Method Summary

- - + + - - + + - - + + + + + + - + - + - + - + + + + + - + - + - + - + - + - + - + @@ -357,7 +382,7 @@

TAG

  • NO_VOLTAGE_SENSOR

    public static final java.lang.String NO_VOLTAGE_SENSOR
    -
    This string is sent in the robot battery telemetry payload to indicate +
    This string is sent in the robot battery telemetry payload to identify that no voltage sensor is available on the robot.
    See Also:
    @@ -365,6 +390,19 @@

    NO_VOLTAGE_SENSOR

  • + + + + @@ -512,10 +550,21 @@

    updateUIInterval

    -
      +
      • hardwareMap

        protected HardwareMap hardwareMap
        +
        the actual hardware map seen by the user
        +
      • +
      + + + +
        +
      • +

        hardwareMapExtra

        +
        protected HardwareMap hardwareMapExtra
        +
        the hardware map in which we keep any extra devices (ones not used by the user) we need to instantiate
      @@ -563,6 +612,15 @@

      close

      public void close()
    + + + +
      +
    • +

      closeHardwareMap

      +
      protected static void closeHardwareMap(HardwareMap hardwareMap)
      +
    • +
    @@ -597,6 +655,26 @@

    getExtantLynxDeviceImpls

    public java.util.List<LynxUsbDeviceImpl> getExtantLynxDeviceImpls()
    + + + +
      +
    • +

      getHardwareDevice

      +
      public <T> T getHardwareDevice(java.lang.Class<? extends T> classOrInterface,
      +                               SerialNumber serialNumber,
      +                               <any> usbScanManagerSupplier)
      +
      Returns the device whose serial number is the one indicated, from the hardware map if possible + but instantiating / opening it if necessary. null is returned if the object cannot be + accessed.
      +
      +
      Parameters:
      +
      classOrInterface - the interface to retrieve on the returned object
      +
      serialNumber - the serial number of the object to retrieve
      +
      usbScanManagerSupplier - how to get a USBScanManager if it ends up we need one
      +
      +
    • +
    @@ -657,31 +735,31 @@

    sendTelemetry

    java.lang.String msg) - +
    • closeMotorControllers

      -
      protected void closeMotorControllers()
      +
      protected static void closeMotorControllers(HardwareMap hardwareMap)
    - +
    • closeServoControllers

      -
      protected void closeServoControllers()
      +
      protected static void closeServoControllers(HardwareMap hardwareMap)
    - +
    • closeAutoCloseOnTeardown

      -
      protected void closeAutoCloseOnTeardown()
      +
      protected static void closeAutoCloseOnTeardown(HardwareMap hardwareMap)
    diff --git a/doc/javadoc/com/qualcomm/ftccommon/FtcEventLoopIdle.html b/doc/javadoc/com/qualcomm/ftccommon/FtcEventLoopIdle.html index 1c36a7187fd..93ccdc48d67 100644 --- a/doc/javadoc/com/qualcomm/ftccommon/FtcEventLoopIdle.html +++ b/doc/javadoc/com/qualcomm/ftccommon/FtcEventLoopIdle.html @@ -285,7 +285,7 @@

    Method Summary

    Methods inherited from class com.qualcomm.ftccommon.FtcEventLoopBase

    -checkForChangedOpModes, enterFirmwareUpdateMode, getLynxUsbDeviceForFirmwareUpdate, getUSBAccessibleLynxDevices, handleCommandActivateConfiguration, handleCommandClearRememberedGroups, handleCommandDeleteConfiguration, handleCommandDisconnectWifiDirect, handleCommandDismissAllDialogs, handleCommandDismissDialog, handleCommandDismissProgress, handleCommandGetCandidateLynxFirmwareImages, handleCommandGetUSBAccessibleLynxModules, handleCommandLynxChangeModuleAddresses, handleCommandLynxFirmwareUpdate, handleCommandRequestConfigurations, handleCommandRequestConfigurationTemplates, handleCommandRequestInspectionReport, handleCommandRequestParticularConfiguration, handleCommandRequestRememberedGroups, handleCommandRestartRobot, handleCommandSaveConfiguration, handleCommandShowDialog, handleCommandShowProgress, handleCommandShowToast, handleCommandStartDriverStationProgramAndManage, handleCommandStartProgrammingMode, handleCommandStopProgrammingMode, processCommand, sendUIState, startUsbScanMangerIfNecessary, updateLynxFirmware +checkForChangedOpModes, enterFirmwareUpdateMode, getLynxUsbDeviceForFirmwareUpdate, getUSBAccessibleLynxDevices, handleCommandActivateConfiguration, handleCommandClearRememberedGroups, handleCommandDeleteConfiguration, handleCommandDisconnectWifiDirect, handleCommandDismissAllDialogs, handleCommandDismissDialog, handleCommandDismissProgress, handleCommandGetCandidateLynxFirmwareImages, handleCommandGetUSBAccessibleLynxModules, handleCommandLynxChangeModuleAddresses, handleCommandLynxFirmwareUpdate, handleCommandRequestAboutInfo, handleCommandRequestConfigurations, handleCommandRequestConfigurationTemplates, handleCommandRequestInspectionReport, handleCommandRequestParticularConfiguration, handleCommandRequestRememberedGroups, handleCommandRestartRobot, handleCommandSaveConfiguration, handleCommandShowDialog, handleCommandShowProgress, handleCommandShowToast, handleCommandStartDriverStationProgramAndManage, handleCommandStartProgrammingMode, handleCommandStopProgrammingMode, handleCommandVisuallyIdentify, processCommand, sendUIState, startUsbScanMangerIfNecessary, talkToParentLynxModule, updateFirmwareOnce, updateLynxFirmware
    All Methods Instance Methods Concrete Methods All Methods Static Methods Instance Methods Concrete Methods 
    Modifier and Type Method and Description close() 
    protected voidcloseAutoCloseOnTeardown() protected static voidcloseAutoCloseOnTeardown(HardwareMap hardwareMap) 
    protected void closeBatteryMonitoring() 
    protected voidcloseMotorControllers() protected static voidcloseHardwareMap(HardwareMap hardwareMap) 
    protected voidcloseServoControllers() protected static voidcloseMotorControllers(HardwareMap hardwareMap) 
    protected static voidcloseServoControllers(HardwareMap hardwareMap) 
    void displayGamePadInfo(java.lang.String activeOpModeName) 
    EventLoopManager getEventLoopManager() 
    java.util.List<LynxUsbDeviceImpl> getExtantLynxDeviceImpls() 
    Gamepad[] getGamepads() 
    <T> TgetHardwareDevice(java.lang.Class<? extends T> classOrInterface, + SerialNumber serialNumber, + <any> usbScanManagerSupplier) +
    Returns the device whose serial number is the one indicated, from the hardware map if possible + but instantiating / opening it if necessary.
    +
    HardwareMap getHardwareMap() 
    java.lang.String getOpMode(java.lang.String extra) 
    void init(EventLoopManager eventLoopManager) 
    void refreshUserTelemetry(TelemetryMessage telemetry, double requestedInterval) @@ -296,22 +321,22 @@

    Method Summary

    interval has passed since the last transmission.
    void restartRobot() 
    void sendBatteryInfo()
    Send robot phone power % and robot battery voltage level to Driver station
    void sendTelemetry(java.lang.String tag, java.lang.String msg) 
    void updateBatteryStatus(BatteryChecker.BatteryStatus status) 
    + + + + + + + + + + + + + +
    Enum Constants 
    Enum Constant and Description
    Cancelled 
    Succeeded 
    TimedOut 
    + + + + + + +
    +
    +
      +
    • + + + +
        +
      • + + +

        Method Detail

        + + + +
          +
        • +

          values

          +
          public static FtcLynxFirmwareUpdateActivity.FwResponseStatus[] values()
          +
          Returns an array containing the constants of this enum type, in +the order they are declared. This method may be used to iterate +over the constants as follows: +
          +for (FtcLynxFirmwareUpdateActivity.FwResponseStatus c : FtcLynxFirmwareUpdateActivity.FwResponseStatus.values())
          +    System.out.println(c);
          +
          +
          +
          Returns:
          +
          an array containing the constants of this enum type, in the order they are declared
          +
          +
        • +
        + + + +
          +
        • +

          valueOf

          +
          public static FtcLynxFirmwareUpdateActivity.FwResponseStatus valueOf(java.lang.String name)
          +
          Returns the enum constant of this type with the specified name. +The string must match exactly an identifier used to declare an +enum constant in this type. (Extraneous whitespace characters are +not permitted.)
          +
          +
          Parameters:
          +
          name - the name of the enum constant to be returned.
          +
          Returns:
          +
          the enum constant with the specified name
          +
          Throws:
          +
          java.lang.IllegalArgumentException - if this enum type has no constant with the specified name
          +
          java.lang.NullPointerException - if the argument is null
          +
          +
        • +
        +
      • +
      +
    • +
    +
    +
    + + + + + + + diff --git a/doc/javadoc/com/qualcomm/ftccommon/FtcLynxFirmwareUpdateActivity.ReceiveLoopCallback.html b/doc/javadoc/com/qualcomm/ftccommon/FtcLynxFirmwareUpdateActivity.ReceiveLoopCallback.html index 46f8873a485..303015c3d8d 100644 --- a/doc/javadoc/com/qualcomm/ftccommon/FtcLynxFirmwareUpdateActivity.ReceiveLoopCallback.html +++ b/doc/javadoc/com/qualcomm/ftccommon/FtcLynxFirmwareUpdateActivity.ReceiveLoopCallback.html @@ -47,7 +47,7 @@ @@ -272,8 +442,8 @@

    SoundInfo

    diff --git a/doc/javadoc/com/qualcomm/ftccommon/SoundPlayer.StopWhat.html b/doc/javadoc/com/qualcomm/ftccommon/SoundPlayer.StopWhat.html new file mode 100644 index 00000000000..c148bd68d7d --- /dev/null +++ b/doc/javadoc/com/qualcomm/ftccommon/SoundPlayer.StopWhat.html @@ -0,0 +1,342 @@ + + + + + +SoundPlayer.StopWhat + + + + + + + + + + + +
    +
    com.qualcomm.ftccommon
    +

    Enum SoundPlayer.StopWhat

    +
    +
    +
      +
    • java.lang.Object
    • +
    • + +
    • +
    +
    + +
    +
    +
      +
    • + +
        +
      • + + +

        Enum Constant Summary

        + + + + + + + + + + + +
        Enum Constants 
        Enum Constant and Description
        All 
        Loops 
        +
      • +
      + +
        +
      • + + +

        Method Summary

        + + + + + + + + + + + + + + +
        All Methods Static Methods Concrete Methods 
        Modifier and TypeMethod and Description
        static SoundPlayer.StopWhatvalueOf(java.lang.String name) +
        Returns the enum constant of this type with the specified name.
        +
        static SoundPlayer.StopWhat[]values() +
        Returns an array containing the constants of this enum type, in +the order they are declared.
        +
        +
          +
        • + + +

          Methods inherited from class java.lang.Enum

          +clone, compareTo, equals, finalize, getDeclaringClass, hashCode, name, ordinal, toString, valueOf
        • +
        +
          +
        • + + +

          Methods inherited from class java.lang.Object

          +getClass, notify, notifyAll, wait, wait, wait
        • +
        +
      • +
      +
    • +
    +
    +
    +
      +
    • + + + +
        +
      • + + +

        Method Detail

        + + + +
          +
        • +

          values

          +
          public static SoundPlayer.StopWhat[] values()
          +
          Returns an array containing the constants of this enum type, in +the order they are declared. This method may be used to iterate +over the constants as follows: +
          +for (SoundPlayer.StopWhat c : SoundPlayer.StopWhat.values())
          +    System.out.println(c);
          +
          +
          +
          Returns:
          +
          an array containing the constants of this enum type, in the order they are declared
          +
          +
        • +
        + + + +
          +
        • +

          valueOf

          +
          public static SoundPlayer.StopWhat valueOf(java.lang.String name)
          +
          Returns the enum constant of this type with the specified name. +The string must match exactly an identifier used to declare an +enum constant in this type. (Extraneous whitespace characters are +not permitted.)
          +
          +
          Parameters:
          +
          name - the name of the enum constant to be returned.
          +
          Returns:
          +
          the enum constant with the specified name
          +
          Throws:
          +
          java.lang.IllegalArgumentException - if this enum type has no constant with the specified name
          +
          java.lang.NullPointerException - if the argument is null
          +
          +
        • +
        +
      • +
      +
    • +
    +
    +
    + + + + + + + diff --git a/doc/javadoc/com/qualcomm/ftccommon/SoundPlayer.html b/doc/javadoc/com/qualcomm/ftccommon/SoundPlayer.html index c3cec169b39..10ff5cbfe2a 100644 --- a/doc/javadoc/com/qualcomm/ftccommon/SoundPlayer.html +++ b/doc/javadoc/com/qualcomm/ftccommon/SoundPlayer.html @@ -17,8 +17,8 @@ catch(err) { } //--> -var methods = {"i0":10,"i1":10,"i2":9,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10,"i10":10,"i11":10}; -var tabs = {65535:["t0","All Methods"],1:["t1","Static Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]}; +var methods = {"i0":9,"i1":10,"i2":9,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":9,"i9":10,"i10":10,"i11":10,"i12":10,"i13":10,"i14":10,"i15":10,"i16":10,"i17":10,"i18":10,"i19":10,"i20":10,"i21":10,"i22":42,"i23":42,"i24":10,"i25":10,"i26":10,"i27":9,"i28":10,"i29":10,"i30":10,"i31":10,"i32":10,"i33":10,"i34":10,"i35":10,"i36":10,"i37":10}; +var tabs = {65535:["t0","All Methods"],1:["t1","Static Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"],32:["t6","Deprecated Methods"]}; var altColor = "altColor"; var rowColor = "rowColor"; var tableTab = "tableTab"; @@ -48,7 +48,7 @@
    See Also:
    -
    play(Context, int)
    +
    startPlaying(Context, int)
    @@ -134,6 +134,14 @@

    Nested Class Summary

    Class and Description +protected static class  +SoundPlayer.CurrentlyPlaying  + + +protected static class  +SoundPlayer.InstanceHolder  + + protected class  SoundPlayer.LoadedSoundCache
    SoundPlayer.LoadedSoundCache keeps track of loaded sounds, mapping sound resource id to loaded @@ -141,9 +149,21 @@

    Nested Class Summary

    +static class  +SoundPlayer.PlaySoundParams  + + +protected static interface  +SoundPlayer.SoundFromFile  + + protected class  SoundPlayer.SoundInfo  + +protected static class  +SoundPlayer.StopWhat  + @@ -160,32 +180,40 @@

    Field Summary

    Field and Description -protected Context -context  +protected SoundPlayer.SoundInfo +currentlyLoadingInfo  -protected int -currentlyLoading  +protected java.util.concurrent.CountDownLatch +currentlyLoadingLatch  -static boolean -DEBUG  +protected java.util.Set<SoundPlayer.CurrentlyPlaying> +currentlyPlayingSounds  -protected java.util.concurrent.ExecutorService -executorService  +protected boolean +isRobotController  protected SoundPlayer.LoadedSoundCache loadedSounds  -protected Looper -looper  +protected java.lang.Object +lock  -protected long -msFinishPlaying  +protected float +masterVolume  + + +static int +msSoundTransmissionFreshness  + + +protected java.util.concurrent.ScheduledExecutorService +scheduledThreadPool  protected SharedPreferences @@ -193,11 +221,11 @@

    Field Summary

    protected float -soundOffLevel  +soundOffVolume  protected float -soundOnLevel  +soundOnVolume  protected SoundPool @@ -208,8 +236,16 @@

    Field Summary

    TAG  -protected static SoundPlayer -theInstance  +protected java.util.concurrent.ExecutorService +threadPool  + + +static boolean +TRACE  + + +protected Tracer +tracer  @@ -241,75 +277,235 @@

    Constructor Summary

    Method Summary

    - + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + - + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + int status)  - + + + + + - + - - - + + + - + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + @@ -348,26 +544,53 @@

    TAG

    - +
    • -

      DEBUG

      -
      public static final boolean DEBUG
      +

      TRACE

      +
      public static boolean TRACE
      +
    • +
    + + + +
      +
    • +

      tracer

      +
      protected Tracer tracer
      +
    • +
    + + + + - + + + +
      +
    • +

      lock

      +
      protected final java.lang.Object lock
      +
    • +
    +
    • -

      theInstance

      -
      protected static SoundPlayer theInstance
      +

      isRobotController

      +
      protected final boolean isRobotController
    @@ -379,22 +602,22 @@

    soundPool

    protected SoundPool soundPool
    -
    +
    • -

      currentlyLoading

      -
      protected volatile int currentlyLoading
      +

      currentlyLoadingLatch

      +
      protected java.util.concurrent.CountDownLatch currentlyLoadingLatch
    - +
    • -

      msFinishPlaying

      -
      protected long msFinishPlaying
      +

      currentlyLoadingInfo

      +
      protected SoundPlayer.SoundInfo currentlyLoadingInfo
    @@ -406,58 +629,67 @@

    loadedSounds

    protected SoundPlayer.LoadedSoundCache loadedSounds
    - +
    • -

      executorService

      -
      protected java.util.concurrent.ExecutorService executorService
      +

      threadPool

      +
      protected java.util.concurrent.ExecutorService threadPool
    - +
    • -

      looper

      -
      protected Looper looper
      +

      scheduledThreadPool

      +
      protected java.util.concurrent.ScheduledExecutorService scheduledThreadPool
    - +
    • -

      context

      -
      protected Context context
      +

      sharedPreferences

      +
      protected SharedPreferences sharedPreferences
    - +
    • -

      sharedPreferences

      -
      protected SharedPreferences sharedPreferences
      +

      soundOnVolume

      +
      protected float soundOnVolume
    - +
    • -

      soundOnLevel

      -
      protected float soundOnLevel
      +

      soundOffVolume

      +
      protected float soundOffVolume
    - + + + +
      +
    • +

      masterVolume

      +
      protected float masterVolume
      +
    • +
    +
    • -

      soundOffLevel

      -
      protected float soundOffLevel
      +

      currentlyPlayingSounds

      +
      protected java.util.Set<SoundPlayer.CurrentlyPlaying> currentlyPlayingSounds
    @@ -512,74 +744,248 @@

    close

    public void close()
    - +
    • -

      startup

      -
      protected void startup()
      +

      prefillSoundCache

      +
      public void prefillSoundCache(int... resourceIds)
      +
      Ensures that these local sounds are also in the local cache
    - +
    • -

      shutdown

      -
      protected void shutdown()
      +

      startPlaying

      +
      public void startPlaying(Context context,
      +                         int resId)
      +
      Asynchronously loads the indicated sound from its resource (if not already loaded), then + initiates its play once any current non-looping sound is finished playing.
      +
      +
      Parameters:
      +
      context - the context in which resId is to be interpreted
      +
      resId - the resource id of the raw resource containing the sound.
      +
    - +
    • -

      play

      -
      public void play(Context context,
      -                 int resId)
      +

      startPlaying

      +
      public void startPlaying(Context context,
      +                         java.io.File file)
      +
    • +
    + + + +
      +
    • +

      startPlaying

      +
      public void startPlaying(Context context,
      +                         int resId,
      +                         SoundPlayer.PlaySoundParams params,
      +                         <any> runWhenStarted,
      +                         java.lang.Runnable runWhenFinished)
      Asynchronously loads the indicated sound from its resource (if not already loaded), then - initiates its play once any current sound is finished playing.
      + initiates its play, optionally waiting for any currently non-looping playing sounds to finish first.
      Parameters:
      context - the context in which resId is to be interpreted
      resId - the resource id of the raw resource containing the sound.
      +
      params - controls how the playback proceeds
      +
      runWhenStarted - executed when the stream starts to play
      +
      runWhenFinished - executed when the stream finishes playing
    - +
    • -

      play

      -
      public void play(Context context,
      -                 int resId,
      -                 boolean waitForCompletion)
      -
      Asynchronously loads the indicated sound from its resource (if not already loaded), then - initiates its play, optionally waiting for any currently playing sound to finish first.
      +

      startPlaying

      +
      public void startPlaying(Context context,
      +                         java.io.File file,
      +                         SoundPlayer.PlaySoundParams params,
      +                         <any> runWhenStarted,
      +                         java.lang.Runnable runWhenFinished)
      +
    • +
    + + + +
      +
    • +

      stopPlayingAll

      +
      public void stopPlayingAll()
      +
      Stops playing all sounds that are currently playing
      +
    • +
    + + + +
      +
    • +

      stopPlayingLoops

      +
      public void stopPlayingLoops()
      +
      Stops playing all sounds that are currently playing in a loop
      +
    • +
    + + + + + + + +
      +
    • +

      preload

      +
      public boolean preload(Context context,
      +                       int resourceId)
      +
      Preloads the sound so as to to reduce delays if the sound is subsequently played.
      +
    • +
    + + + +
      +
    • +

      preload

      +
      public boolean preload(Context context,
      +                       java.io.File file)
      +
      Preloads the sound so as to to reduce delays if the sound is subsequently played.
      +
    • +
    + + + +
      +
    • +

      setMasterVolume

      +
      public void setMasterVolume(float masterVolume)
      +
      Sets the master volume control that is applied to all played sounds
      -
      Parameters:
      -
      context - the context in which resId is to be interpreted
      -
      resId - the resource id of the raw resource containing the sound.
      -
      waitForCompletion - whether to wait for any current sound to finish playing first or not
      +
      See Also:
      +
      getMasterVolume()
    - + + + +
      +
    • +

      getMasterVolume

      +
      public float getMasterVolume()
      +
      Returns the master volume control that is applied to all played sounds
      +
      +
      See Also:
      +
      setMasterVolume(float)
      +
      +
    • +
    + + + +
      +
    • +

      play

      +
      @Deprecated
      +public void play(Context context,
      +                             int resId)
      +
      Deprecated. use startPlaying(Context, int) instead
      +
    • +
    + + + +
      +
    • +

      play

      +
      @Deprecated
      +public void play(Context context,
      +                             int resId,
      +                             boolean waitForCompletion)
      +
      Deprecated. use #startPlaying(Context, int, PlaySoundParams, Consumer, Runnable) instead
      +
    • +
    + + + +
      +
    • +

      loadAndStartPlaying

      +
      protected void loadAndStartPlaying(Context context,
      +                                   int resourceId,
      +                                   SoundPlayer.PlaySoundParams params,
      +                                   <any> runWhenStarted,
      +                                   java.lang.Runnable runWhenFinished)
      +
    • +
    + + + +
      +
    • +

      loadAndStartPlaying

      +
      protected void loadAndStartPlaying(Context context,
      +                                   java.io.File file,
      +                                   SoundPlayer.PlaySoundParams params,
      +                                   <any> runWhenStarted,
      +                                   java.lang.Runnable runWhenFinished)
      +
    • +
    + + + +
      +
    • +

      ensureLoaded

      +
      protected SoundPlayer.SoundInfo ensureLoaded(Context context,
      +                                             int resourceId)
      +
    • +
    + + + +
      +
    • +

      ensureLoaded

      +
      protected SoundPlayer.SoundInfo ensureLoaded(Context context,
      +                                             java.io.File file)
      +
    • +
    + + + +
      +
    • +

      isLocalSoundOn

      +
      public boolean isLocalSoundOn()
      +
    • +
    +
    • -

      loadAndPlay

      -
      protected void loadAndPlay(Context context,
      -                           int resourceId,
      -                           boolean waitForCompletion)
      -
      Loads the requested sound if necessary, then (eventually) plays it. - Note: this always runs on our dedicate executor thread. We do that because - that allows us to have a looper that *only* sees load completions, which will - prevent us from accepting new play requests while we're waiting for loads to - complete.
      +

      startPlayingLoadedSound

      +
      protected void startPlayingLoadedSound(SoundPlayer.SoundInfo soundInfo,
      +                                       SoundPlayer.PlaySoundParams paramsIn,
      +                                       <any> runWhenStarted,
      +                                       java.lang.Runnable runWhenFinished)
    @@ -592,6 +998,16 @@

    getMsDuration

    int resourceId) +
    + + +
      +
    • +

      getMsDuration

      +
      protected int getMsDuration(Context context,
      +                            java.io.File file)
      +
    • +
    @@ -601,43 +1017,142 @@

    waitForLoadCompletion

    protected void waitForLoadCompletion()
    - +
    • -

      playLoadedSound

      -
      protected void playLoadedSound(SoundPlayer.SoundInfo soundInfo,
      -                               boolean waitForCompletion)
      +

      onLoadComplete

      +
      public void onLoadComplete(SoundPool soundPool,
      +                           int sampleId,
      +                           int status)
    - +
    • -

      getCurrentMilliseconds

      -
      protected long getCurrentMilliseconds()
      +

      getMsNow

      +
      protected long getMsNow()
    - + -
      +
      • -

        onLoadComplete

        -
        public void onLoadComplete(SoundPool soundPool,
        -                           int sampleId,
        -                           int status)
        -
        Called when a sound has completed loading.
        +

        ensureLoaded

        +
        protected SoundPlayer.SoundInfo ensureLoaded(java.lang.String hashString,
        +                                             SoundPlayer.SoundFromFile ifAbsent)
        +
        returns a new ref on the returned SoundPlayer.SoundInfo; caller must releaseRef()
        +
      • +
      + + + +
        +
      • +

        ensureCached

        +
        protected void ensureCached(Context context,
        +                            int resId)
        +
        Ensures this local sound is also in the local cache.
        +
      • +
      + + + + + + + +
        +
      • +

        handleCommandPlaySound

        +
        public CallbackResult handleCommandPlaySound(java.lang.String extra)
        +
      • +
      + + + +
        +
      • +

        handleCommandStopPlayingSounds

        +
        public CallbackResult handleCommandStopPlayingSounds(Command stopPlayingSoundsCommand)
        +
      • +
      + + + +
        +
      • +

        copy

        +
        protected static void copy(java.io.InputStream inputStream,
        +                           java.io.OutputStream outputStream,
        +                           int cbToCopy)
        +                    throws java.io.IOException
        -
        Parameters:
        -
        soundPool - SoundPool object from the load() method
        -
        sampleId - the sample ID of the sound loaded.
        -
        status - the status of the load operation (0 = success)
        +
        Throws:
        +
        java.io.IOException
      + + + +
        +
      • +

        handleCommandRequestSound

        +
        public CallbackResult handleCommandRequestSound(Command requestSoundCommand)
        +
      • +
      + + + +
        +
      • +

        safeClose

        +
        protected void safeClose(java.lang.Object closeable)
        +
      • +
      + + + + + + + + + + + +
        +
      • +

        play

        +
        public void play(Context context,
        +                 java.io.File file,
        +                 float volume,
        +                 int loop,
        +                 float rate)
        +
      • +
    @@ -666,7 +1181,7 @@

    onLoadComplete

    + + + + - + - + @@ -177,26 +181,38 @@

    Method Summary

    + + + + + + + + - + - + - + + + + + - + - + @@ -243,12 +259,21 @@

    moduleAddress

    -
      +
      • moduleAddressChangeable

        protected boolean moduleAddressChangeable
      + + + +
        +
      • +

        firmwareVersionString

        +
        protected java.lang.String firmwareVersionString
        +
      • +
    @@ -332,12 +357,39 @@

    isModuleAddressChangeable

    -
      +
      • setModuleAddressChangeable

        public void setModuleAddressChangeable(boolean moduleAddressChangeable)
      + + + +
        +
      • +

        getFirmwareVersionString

        +
        public java.lang.String getFirmwareVersionString()
        +
      • +
      + + + +
        +
      • +

        getFinishedFirmwareVersionString

        +
        public java.lang.String getFinishedFirmwareVersionString()
        +
      • +
      + + + +
        +
      • +

        setFirmwareVersionString

        +
        public void setFirmwareVersionString(java.lang.String firmwareVersionString)
        +
      • +
    diff --git a/doc/javadoc/com/qualcomm/ftccommon/UpdateUI.Callback.html b/doc/javadoc/com/qualcomm/ftccommon/UpdateUI.Callback.html index 72680b500dd..ba92a2c49a1 100644 --- a/doc/javadoc/com/qualcomm/ftccommon/UpdateUI.Callback.html +++ b/doc/javadoc/com/qualcomm/ftccommon/UpdateUI.Callback.html @@ -181,7 +181,7 @@

    Method Summary

    - + @@ -313,13 +313,13 @@

    updateUi

    Gamepad[] gamepads) - +
    • networkConnectionUpdate

      -
      public void networkConnectionUpdate(WifiDirectAssistant.Event event)
      +
      public void networkConnectionUpdate(NetworkConnection.NetworkEvent event)
    diff --git a/doc/javadoc/com/qualcomm/ftccommon/UpdateUI.html b/doc/javadoc/com/qualcomm/ftccommon/UpdateUI.html index 93cd5d663cf..3a07dfb1049 100644 --- a/doc/javadoc/com/qualcomm/ftccommon/UpdateUI.html +++ b/doc/javadoc/com/qualcomm/ftccommon/UpdateUI.html @@ -47,7 +47,7 @@ diff --git a/doc/javadoc/com/qualcomm/ftccommon/package-summary.html b/doc/javadoc/com/qualcomm/ftccommon/package-summary.html index 557545ba462..e889fe9e1b8 100644 --- a/doc/javadoc/com/qualcomm/ftccommon/package-summary.html +++ b/doc/javadoc/com/qualcomm/ftccommon/package-summary.html @@ -96,6 +96,10 @@

    Package com.qualcomm.ftccommon

    + + + + - - - - - - - - + + + + + + + + + + + + + + + + @@ -169,6 +181,14 @@

    Package com.qualcomm.ftccommon

    + + + + + + + + - + + + + + + + + + + + + + - + @@ -284,12 +316,20 @@

    Package com.qualcomm.ftccommon

    + + + + + + + +
    All Methods Static Methods Instance Methods Concrete Methods All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods 
    Modifier and Type Method and Description
    voidclose() static SoundPlayer.SoundInfoaddRef(SoundPlayer.SoundInfo soundInfo) 
    protected longgetCurrentMilliseconds() voidclose() 
    protected static voidcopy(java.io.InputStream inputStream, + java.io.OutputStream outputStream, + int cbToCopy) 
    protected voidensureCached(Context context, + int resId) +
    Ensures this local sound is also in the local cache.
    +
    protected SoundPlayer.SoundInfoensureCached(java.lang.String hashString, + SoundPlayer.SoundFromFile ifAbsent) +
    returns a new ref on the returned SoundPlayer.SoundInfo; caller must releaseRef()
    +
    protected SoundPlayer.SoundInfoensureLoaded(Context context, + java.io.File file) 
    protected SoundPlayer.SoundInfoensureLoaded(Context context, + int resourceId) 
    protected SoundPlayer.SoundInfoensureLoaded(java.lang.String hashString, + SoundPlayer.SoundFromFile ifAbsent) +
    returns a new ref on the returned SoundPlayer.SoundInfo; caller must releaseRef()
    +
    static SoundPlayer getInstance() 
    floatgetMasterVolume() +
    Returns the master volume control that is applied to all played sounds
    +
    protected intgetMsDuration(Context context, + java.io.File file) 
    protected int getMsDuration(Context context, int resourceId) 
    protected longgetMsNow() 
    CallbackResulthandleCommandPlaySound(java.lang.String extra) 
    CallbackResulthandleCommandRequestSound(Command requestSoundCommand) 
    CallbackResulthandleCommandStopPlayingSounds(Command stopPlayingSoundsCommand) 
    protected voidloadAndPlay(Context context, - int resourceId, - boolean waitForCompletion) -
    Loads the requested sound if necessary, then (eventually) plays it.
    -
    internalStopPlaying(SoundPlayer.StopWhat stopWhat) 
    booleanisLocalSoundOn() 
    protected voidloadAndStartPlaying(Context context, + java.io.File file, + SoundPlayer.PlaySoundParams params, + <any> runWhenStarted, + java.lang.Runnable runWhenFinished) 
    protected voidloadAndStartPlaying(Context context, + int resourceId, + SoundPlayer.PlaySoundParams params, + <any> runWhenStarted, + java.lang.Runnable runWhenFinished) 
    void onLoadComplete(SoundPool soundPool, int sampleId, - int status) -
    Called when a sound has completed loading.
    -
    voidplay(Context context, + java.io.File file, + float volume, + int loop, + float rate) 
    void play(Context context, int resId) -
    Asynchronously loads the indicated sound from its resource (if not already loaded), then - initiates its play once any current sound is finished playing.
    +
    Deprecated.  + +
    void play(Context context, int resId, boolean waitForCompletion) -
    Asynchronously loads the indicated sound from its resource (if not already loaded), then - initiates its play, optionally waiting for any currently playing sound to finish first.
    +
    Deprecated.  +
    use #startPlaying(Context, int, PlaySoundParams, Consumer, Runnable) instead
    +
    protected voidplayLoadedSound(SoundPlayer.SoundInfo soundInfo, - boolean waitForCompletion) 
    voidprefillSoundCache(int... resourceIds) +
    Ensures that these local sounds are also in the local cache
    +
    booleanpreload(Context context, + java.io.File file) +
    Preloads the sound so as to to reduce delays if the sound is subsequently played.
    +
    booleanpreload(Context context, + int resourceId) +
    Preloads the sound so as to to reduce delays if the sound is subsequently played.
    +
    static voidreleaseRef(SoundPlayer.SoundInfo soundInfo) 
    protected voidshutdown() safeClose(java.lang.Object closeable) 
    voidsetMasterVolume(float masterVolume) +
    Sets the master volume control that is applied to all played sounds
    +
    voidstartPlaying(Context context, + java.io.File file) 
    voidstartPlaying(Context context, + java.io.File file, + SoundPlayer.PlaySoundParams params, + <any> runWhenStarted, + java.lang.Runnable runWhenFinished) 
    voidstartPlaying(Context context, + int resId) +
    Asynchronously loads the indicated sound from its resource (if not already loaded), then + initiates its play once any current non-looping sound is finished playing.
    +
    voidstartPlaying(Context context, + int resId, + SoundPlayer.PlaySoundParams params, + <any> runWhenStarted, + java.lang.Runnable runWhenFinished) +
    Asynchronously loads the indicated sound from its resource (if not already loaded), then + initiates its play, optionally waiting for any currently non-looping playing sounds to finish first.
    +
    protected voidstartup() startPlayingLoadedSound(SoundPlayer.SoundInfo soundInfo, + SoundPlayer.PlaySoundParams paramsIn, + <any> runWhenStarted, + java.lang.Runnable runWhenFinished) 
    voidstopPlayingAll() +
    Stops playing all sounds that are currently playing
    +
    voidstopPlayingLoops() +
    Stops playing all sounds that are currently playing in a loop
    +
    protected void waitForLoadCompletion() 
    Field and Description
    protected java.lang.StringfirmwareVersionString 
    protected int moduleAddress 
    protected boolean moduleAddressChangeable 
    protected SerialNumber serialNumber 
    Method and Description
    java.lang.StringgetFinishedFirmwareVersionString() 
    java.lang.StringgetFirmwareVersionString() 
    int getModuleAddress() 
    SerialNumber getSerialNumber() 
    boolean isModuleAddressChangeable() 
    voidsetFirmwareVersionString(java.lang.String firmwareVersionString) 
    void setModuleAddress(int moduleAddress) 
    void setModuleAddressChangeable(boolean moduleAddressChangeable) 
    void setSerialNumber(SerialNumber serialNumber) 
    voidnetworkConnectionUpdate(WifiDirectAssistant.Event event) networkConnectionUpdate(NetworkConnection.NetworkEvent event) 
    void  
    SoundPlayer.SoundFromFile 
    UsbModuleAttachmentHandler
    UsbModuleAttachmentHandler is a notification interface through which policies for dealing @@ -114,14 +118,6 @@

    Package com.qualcomm.ftccommon

    AboutActivity 
    AboutActivity.Item 
    ClassManagerFactory
    A helper for classes that want to inspect the list of classes packaged with an APK.
    @@ -134,6 +130,22 @@

    Package com.qualcomm.ftccommon

    CommandList.CmdPlaySound 
    CommandList.CmdRequestSound 
    CommandList.CmdStopPlayingSounds 
    CommandList.CmdVisuallyIdentify 
    CommandList.LynxAddressChangeRequest  
    FtcAboutActivity 
    FtcAboutActivity.AboutFragment 
    FtcAdvancedRCSettingsActivity
    FtcAdvancedRCSettingsActivity manages the editing of advanced RC settings
    @@ -255,16 +275,28 @@

    Package com.qualcomm.ftccommon

    UpdateUISoundPlayer.CurrentlyPlaying 
    SoundPlayer.InstanceHolder 
    SoundPlayer.PlaySoundParams  
    UpdateUI 
    USBAccessibleLynxModule
    A simple utility class holding the serial number of a USB accessible lynx module and (optionally) its module address
    ViewLogsActivity  
     
    FtcLynxFirmwareUpdateActivity.FwResponseStatus 
    LaunchActivityConstantsList.RequestCode
    Used internally to distinguish the results coming back from various launched (sub)activities
    SoundPlayer.StopWhat 
    diff --git a/doc/javadoc/com/qualcomm/ftccommon/package-tree.html b/doc/javadoc/com/qualcomm/ftccommon/package-tree.html index 4a2dc4fe461..e39720ee7fc 100644 --- a/doc/javadoc/com/qualcomm/ftccommon/package-tree.html +++ b/doc/javadoc/com/qualcomm/ftccommon/package-tree.html @@ -85,26 +85,16 @@

    Class Hierarchy

  • com.qualcomm.ftccommon.FtcWifiDirectRememberedGroupsActivity.WifiP2pGroupItemAdapter
  • -
  • com.qualcomm.ftccommon.AboutActivity.Item
  • -
  • java.util.AbstractMap<K,V> (implements java.util.Map<K,V>) -
      -
    • java.util.HashMap<K,V> (implements java.lang.Cloneable, java.util.Map<K,V>, java.io.Serializable) - -
    • -
    -
  • Binder
  • com.qualcomm.ftccommon.ClassManagerFactory
  • +
  • com.qualcomm.ftccommon.CommandList.CmdPlaySound
  • +
  • com.qualcomm.ftccommon.CommandList.CmdRequestSound
  • +
  • com.qualcomm.ftccommon.CommandList.CmdStopPlayingSounds
  • +
  • com.qualcomm.ftccommon.CommandList.CmdVisuallyIdentify
  • com.qualcomm.ftccommon.CommandList.LynxAddressChangeRequest
  • com.qualcomm.ftccommon.CommandList.LynxAddressChangeRequest.AddressChange
  • com.qualcomm.ftccommon.CommandList.LynxFirmwareImagesResp
  • @@ -148,12 +138,22 @@

    Class Hierarchy

  • com.qualcomm.ftccommon.LaunchActivityConstantsList
  • PreferenceFragment
  • PreferenceFragment +
  • +
  • PreferenceFragment + +
  • +
  • RefCounted +
  • RobotCoreCommandList @@ -167,45 +167,48 @@

    Class Hierarchy

  • com.qualcomm.ftccommon.SoundPlayer
  • -
  • com.qualcomm.ftccommon.SoundPlayer.SoundInfo
  • +
  • com.qualcomm.ftccommon.SoundPlayer.CurrentlyPlaying
  • +
  • com.qualcomm.ftccommon.SoundPlayer.InstanceHolder
  • +
  • com.qualcomm.ftccommon.SoundPlayer.LoadedSoundCache
  • +
  • com.qualcomm.ftccommon.SoundPlayer.PlaySoundParams
  • ThemedActivity
  • ThemedActivity
  • ThemedActivity
  • ThemedActivity
  • ThemedActivity
  • ThemedActivity
  • ThemedActivity
  • ThemedActivity
  • com.qualcomm.ftccommon.UpdateUI
  • @@ -219,6 +222,7 @@

    Interface Hierarchy

    Enum Hierarchy

    @@ -227,8 +231,10 @@

    Enum Hierarchy

    diff --git a/doc/javadoc/com/qualcomm/robotcore/eventloop/EventLoopManager.html b/doc/javadoc/com/qualcomm/robotcore/eventloop/EventLoopManager.html index 2a5e79c0125..2c056c6d8b3 100644 --- a/doc/javadoc/com/qualcomm/robotcore/eventloop/EventLoopManager.html +++ b/doc/javadoc/com/qualcomm/robotcore/eventloop/EventLoopManager.html @@ -105,10 +105,15 @@

    Class EventLoopManager

    • +
      +
      All Implemented Interfaces:
      +
      SyncdDevice.Manager
      +


      public class EventLoopManager
      -extends java.lang.Object
      +extends java.lang.Object +implements SyncdDevice.Manager
      Event Loop Manager

      Takes RobocolDatagram messages, converts them into the appropriate data type, and then passes it @@ -282,7 +287,7 @@

      Method Summary

      CallbackResult -onNetworkConnectionEvent(NetworkConnection.Event event)  +onNetworkConnectionEvent(NetworkConnection.NetworkEvent event)  CallbackResult @@ -652,13 +657,13 @@

      refreshSystemTelemetry

      without incurring undo overhead.
    - +
    • onNetworkConnectionEvent

      -
      public CallbackResult onNetworkConnectionEvent(NetworkConnection.Event event)
      +
      public CallbackResult onNetworkConnectionEvent(NetworkConnection.NetworkEvent event)
    @@ -716,6 +721,8 @@

    registerSyncdDevice

    public void registerSyncdDevice(SyncdDevice device)
    Register a sync'd device
    +
    Specified by:
    +
    registerSyncdDevice in interface SyncdDevice.Manager
    Parameters:
    device - sync'd device
    See Also:
    @@ -733,6 +740,8 @@

    unregisterSyncdDevice

    Unregisters a device from this event loop. It is specifically permitted to unregister a device which is not currently registered; such an operation has no effect.
    +
    Specified by:
    +
    unregisterSyncdDevice in interface SyncdDevice.Manager
    Parameters:
    device - the device to be unregistered. May not be null.
    See Also:
    diff --git a/doc/javadoc/com/qualcomm/robotcore/eventloop/SyncdDevice.Manager.html b/doc/javadoc/com/qualcomm/robotcore/eventloop/SyncdDevice.Manager.html new file mode 100644 index 00000000000..0108a44eb16 --- /dev/null +++ b/doc/javadoc/com/qualcomm/robotcore/eventloop/SyncdDevice.Manager.html @@ -0,0 +1,239 @@ + + + + + +SyncdDevice.Manager + + + + + + + + + + + +
    +
    com.qualcomm.robotcore.eventloop
    +

    Interface SyncdDevice.Manager

    +
    +
    +
    +
      +
    • +
      +
      All Known Implementing Classes:
      +
      EventLoopManager
      +
      +
      +
      Enclosing interface:
      +
      SyncdDevice
      +
      +
      +
      +
      public static interface SyncdDevice.Manager
      +
    • +
    +
    +
    + +
    +
    +
      +
    • + +
        +
      • + + +

        Method Detail

        + + + +
          +
        • +

          registerSyncdDevice

          +
          void registerSyncdDevice(SyncdDevice device)
          +
        • +
        + + + +
          +
        • +

          unregisterSyncdDevice

          +
          void unregisterSyncdDevice(SyncdDevice device)
          +
        • +
        +
      • +
      +
    • +
    +
    +
    + + + + + + + diff --git a/doc/javadoc/com/qualcomm/robotcore/eventloop/SyncdDevice.ShutdownReason.html b/doc/javadoc/com/qualcomm/robotcore/eventloop/SyncdDevice.ShutdownReason.html index 6387b0f5bef..bc8613e81fb 100644 --- a/doc/javadoc/com/qualcomm/robotcore/eventloop/SyncdDevice.ShutdownReason.html +++ b/doc/javadoc/com/qualcomm/robotcore/eventloop/SyncdDevice.ShutdownReason.html @@ -47,8 +47,8 @@
    Specified by:
    setPIDCoefficients in interface DcMotorEx
    @@ -497,6 +575,88 @@

    setPIDCoefficients

    + + + + + + + + + + + + @@ -517,6 +677,28 @@

    getPIDCoefficients

    + + + +
      +
    • +

      getPIDFCoefficients

      +
      public PIDFCoefficients getPIDFCoefficients(DcMotor.RunMode mode)
      +
      Description copied from interface: DcMotorEx
      +
      Returns the PIDF control coefficients used when running in the indicated mode + on this motor.
      +
      +
      Specified by:
      +
      getPIDFCoefficients in interface DcMotorEx
      +
      Parameters:
      +
      mode - either RunMode#RUN_USING_ENCODER or RunMode#RUN_TO_POSITION
      +
      Returns:
      +
      the PIDF control coefficients used when running in the indicated mode on this motor
      +
      See Also:
      +
      #setPIDFCoefficients(RunMode, PIDFCoefficients)
      +
      +
    • +
    diff --git a/doc/javadoc/com/qualcomm/robotcore/hardware/DeviceManager.DeviceType.html b/doc/javadoc/com/qualcomm/robotcore/hardware/DeviceManager.UsbDeviceType.html similarity index 66% rename from doc/javadoc/com/qualcomm/robotcore/hardware/DeviceManager.DeviceType.html rename to doc/javadoc/com/qualcomm/robotcore/hardware/DeviceManager.UsbDeviceType.html index 4e8f991913a..ab4681f2332 100644 --- a/doc/javadoc/com/qualcomm/robotcore/hardware/DeviceManager.DeviceType.html +++ b/doc/javadoc/com/qualcomm/robotcore/hardware/DeviceManager.UsbDeviceType.html @@ -3,7 +3,7 @@ -DeviceManager.DeviceType +DeviceManager.UsbDeviceType @@ -11,13 +11,13 @@ + + + + + + + + + +
    +
    com.qualcomm.robotcore.hardware
    +

    Enum MotorControlAlgorithm

    +
    +
    +
      +
    • java.lang.Object
    • +
    • + +
    • +
    +
    + +
    +
    +
      +
    • + +
        +
      • + + +

        Enum Constant Summary

        + + + + + + + + + + + + + + +
        Enum Constants 
        Enum Constant and Description
        LegacyPID +
        Deprecated.  +
        Switch to PIDF instead
        +
        +
        PIDF 
        Unknown 
        +
      • +
      + +
        +
      • + + +

        Method Summary

        + + + + + + + + + + + + + + +
        All Methods Static Methods Concrete Methods 
        Modifier and TypeMethod and Description
        static MotorControlAlgorithmvalueOf(java.lang.String name) +
        Returns the enum constant of this type with the specified name.
        +
        static MotorControlAlgorithm[]values() +
        Returns an array containing the constants of this enum type, in +the order they are declared.
        +
        +
          +
        • + + +

          Methods inherited from class java.lang.Enum

          +clone, compareTo, equals, finalize, getDeclaringClass, hashCode, name, ordinal, toString, valueOf
        • +
        +
          +
        • + + +

          Methods inherited from class java.lang.Object

          +getClass, notify, notifyAll, wait, wait, wait
        • +
        +
      • +
      +
    • +
    +
    +
    +
      +
    • + + + +
        +
      • + + +

        Method Detail

        + + + +
          +
        • +

          values

          +
          public static MotorControlAlgorithm[] values()
          +
          Returns an array containing the constants of this enum type, in +the order they are declared. This method may be used to iterate +over the constants as follows: +
          +for (MotorControlAlgorithm c : MotorControlAlgorithm.values())
          +    System.out.println(c);
          +
          +
          +
          Returns:
          +
          an array containing the constants of this enum type, in the order they are declared
          +
          +
        • +
        + + + +
          +
        • +

          valueOf

          +
          public static MotorControlAlgorithm valueOf(java.lang.String name)
          +
          Returns the enum constant of this type with the specified name. +The string must match exactly an identifier used to declare an +enum constant in this type. (Extraneous whitespace characters are +not permitted.)
          +
          +
          Parameters:
          +
          name - the name of the enum constant to be returned.
          +
          Returns:
          +
          the enum constant with the specified name
          +
          Throws:
          +
          java.lang.IllegalArgumentException - if this enum type has no constant with the specified name
          +
          java.lang.NullPointerException - if the argument is null
          +
          +
        • +
        +
      • +
      +
    • +
    +
    +
    + + + + + + + diff --git a/doc/javadoc/com/qualcomm/robotcore/hardware/NormalizedColorSensor.html b/doc/javadoc/com/qualcomm/robotcore/hardware/NormalizedColorSensor.html index 755fc7c958c..7517fe75da7 100644 --- a/doc/javadoc/com/qualcomm/robotcore/hardware/NormalizedColorSensor.html +++ b/doc/javadoc/com/qualcomm/robotcore/hardware/NormalizedColorSensor.html @@ -47,7 +47,7 @@
    @@ -273,7 +311,7 @@

    PIDCoefficients

    diff --git a/doc/javadoc/com/qualcomm/robotcore/hardware/PIDFCoefficients.html b/doc/javadoc/com/qualcomm/robotcore/hardware/PIDFCoefficients.html new file mode 100644 index 00000000000..9d18a5c3b00 --- /dev/null +++ b/doc/javadoc/com/qualcomm/robotcore/hardware/PIDFCoefficients.html @@ -0,0 +1,430 @@ + + + + + +PIDFCoefficients + + + + + + + + + + + +
    +
    com.qualcomm.robotcore.hardware
    +

    Class PIDFCoefficients

    +
    +
    +
      +
    • java.lang.Object
    • +
    • +
        +
      • com.qualcomm.robotcore.hardware.PIDFCoefficients
      • +
      +
    • +
    +
    + +
    +
    + +
    +
    +
      +
    • + +
        +
      • + + +

        Field Detail

        + + + +
          +
        • +

          p

          +
          public double p
          +
        • +
        + + + +
          +
        • +

          i

          +
          public double i
          +
        • +
        + + + +
          +
        • +

          d

          +
          public double d
          +
        • +
        + + + +
          +
        • +

          f

          +
          public double f
          +
        • +
        + + + + +
      • +
      + +
        +
      • + + +

        Constructor Detail

        + + + +
          +
        • +

          PIDFCoefficients

          +
          public PIDFCoefficients()
          +
        • +
        + + + +
          +
        • +

          PIDFCoefficients

          +
          public PIDFCoefficients(double p,
          +                        double i,
          +                        double d,
          +                        double f,
          +                        MotorControlAlgorithm algorithm)
          +
        • +
        + + + +
          +
        • +

          PIDFCoefficients

          +
          public PIDFCoefficients(double p,
          +                        double i,
          +                        double d,
          +                        double f)
          +
        • +
        + + + + + + + + +
      • +
      + +
        +
      • + + +

        Method Detail

        + + + +
          +
        • +

          toString

          +
          public java.lang.String toString()
          +
          +
          Overrides:
          +
          toString in class java.lang.Object
          +
          +
        • +
        +
      • +
      +
    • +
    +
    +
    + + + + + + + diff --git a/doc/javadoc/com/qualcomm/robotcore/hardware/PwmControl.PwmRange.html b/doc/javadoc/com/qualcomm/robotcore/hardware/PwmControl.PwmRange.html index 6717511473c..b375cd9d04c 100644 --- a/doc/javadoc/com/qualcomm/robotcore/hardware/PwmControl.PwmRange.html +++ b/doc/javadoc/com/qualcomm/robotcore/hardware/PwmControl.PwmRange.html @@ -163,11 +163,19 @@

    Field Summary

    +static double +usPulseLowerDefault  + + double usPulseUpper
    usPulseLower is the maximum PWM rate used, in microseconds.
    + +static double +usPulseUpperDefault  + @@ -256,6 +264,32 @@

    usFrameDefault

    + + + +
      +
    • +

      usPulseUpperDefault

      +
      public static final double usPulseUpperDefault
      +
      +
      See Also:
      +
      Constant Field Values
      +
      +
    • +
    + + + +
      +
    • +

      usPulseLowerDefault

      +
      public static final double usPulseLowerDefault
      +
      +
      See Also:
      +
      Constant Field Values
      +
      +
    • +
    diff --git a/doc/javadoc/com/qualcomm/robotcore/hardware/PwmControl.html b/doc/javadoc/com/qualcomm/robotcore/hardware/PwmControl.html index 66d004e4465..1632e900256 100644 --- a/doc/javadoc/com/qualcomm/robotcore/hardware/PwmControl.html +++ b/doc/javadoc/com/qualcomm/robotcore/hardware/PwmControl.html @@ -47,7 +47,7 @@