() {
@Override public String value() {
return String.format(Locale.getDefault(), "%.3f",
Math.sqrt(gravity.xAccel*gravity.xAccel
+ gravity.yAccel*gravity.yAccel
+ gravity.zAccel*gravity.zAccel));
}
});
}
//----------------------------------------------------------------------------------------------
// Formatting
//----------------------------------------------------------------------------------------------
String formatAngle(AngleUnit angleUnit, double angle) {
return formatDegrees(AngleUnit.DEGREES.fromUnit(angleUnit, angle));
}
String formatDegrees(double degrees){
return String.format(Locale.getDefault(), "%.1f", AngleUnit.DEGREES.normalize(degrees));
}
}
================================================
FILE: FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorBNO055IMUCalibration.java
================================================
/* Copyright (c) 2017 FIRST. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided that
* the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* Neither the name of FIRST nor the names of its contributors may be used to endorse or
* promote products derived from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
* LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.firstinspires.ftc.robotcontroller.external.samples;
import com.qualcomm.hardware.adafruit.AdafruitBNO055IMU;
import com.qualcomm.hardware.bosch.BNO055IMU;
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.util.ReadWriteFile;
import org.firstinspires.ftc.robotcore.external.Func;
import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
import org.firstinspires.ftc.robotcore.external.navigation.AxesOrder;
import org.firstinspires.ftc.robotcore.external.navigation.AxesReference;
import org.firstinspires.ftc.robotcore.external.navigation.Orientation;
import org.firstinspires.ftc.robotcore.internal.system.AppUtil;
import java.io.File;
import java.util.Locale;
/**
* {@link SensorBNO055IMUCalibration} calibrates the IMU accelerometer per
* "Section 3.11 Calibration" of the BNO055 specification.
*
* Manual calibration of the IMU is definitely NOT necessary: except for the magnetometer
* (which is not used by the default {@link BNO055IMU.SensorMode#IMU
* SensorMode#IMU}), the BNO055 is internally self-calibrating and thus can be very successfully
* used without manual intervention. That said, performing a one-time calibration, saving the
* results persistently, then loading them again at each run can help reduce the time that automatic
* calibration requires.
*
* This summary of the calibration process, from
* Intel, is informative:
*
* "This device requires calibration in order to operate accurately. [...] Calibration data is
* lost on a power cycle. See one of the examples for a description of how to calibrate the device,
* but in essence:
*
* There is a calibration status register available [...] that returns the calibration status
* of the accelerometer (ACC), magnetometer (MAG), gyroscope (GYR), and overall system (SYS).
* Each of these values range from 0 (uncalibrated) to 3 (fully calibrated). Calibration [ideally]
* involves certain motions to get all 4 values at 3. The motions are as follows (though see the
* datasheet for more information):
*
*
* GYR: Simply let the sensor sit flat for a few seconds.
* ACC: Move the sensor in various positions. Start flat, then rotate slowly by 45
* degrees, hold for a few seconds, then continue rotating another 45 degrees and
* hold, etc. 6 or more movements of this type may be required. You can move through
* any axis you desire, but make sure that the device is lying at least once
* perpendicular to the x, y, and z axis.
* MAG: Move slowly in a figure 8 pattern in the air, until the calibration values reaches 3.
* SYS: This will usually reach 3 when the other items have also reached 3. If not, continue
* slowly moving the device though various axes until it does."
*
*
* To calibrate the IMU, run this sample opmode with a gamepad attached to the driver station.
* Once the IMU has reached sufficient calibration as reported on telemetry, press the 'A'
* button on the gamepad to write the calibration to a file. That file can then be indicated
* later when running an opmode which uses the IMU.
*
* Note: if your intended uses of the IMU do not include use of all its sensors (for exmaple,
* you might not use the magnetometer), then it makes little sense for you to wait for full
* calibration of the sensors you are not using before saving the calibration data. Indeed,
* it appears that in a SensorMode that doesn't use the magnetometer (for example), the
* magnetometer cannot actually be calibrated.
*
* @see AdafruitBNO055IMU
* @see BNO055IMU.Parameters#calibrationDataFile
* @see BNO055 product page
* @see BNO055 specification
*/
@TeleOp(name = "Sensor: BNO055 IMU Calibration", group = "Sensor")
@Disabled // Uncomment this to add to the opmode list
public class SensorBNO055IMUCalibration extends LinearOpMode
{
//----------------------------------------------------------------------------------------------
// State
//----------------------------------------------------------------------------------------------
// Our sensors, motors, and other devices go here, along with other long term state
BNO055IMU imu;
// State used for updating telemetry
Orientation angles;
//----------------------------------------------------------------------------------------------
// Main logic
//----------------------------------------------------------------------------------------------
@Override public void runOpMode() {
telemetry.log().setCapacity(12);
telemetry.log().add("");
telemetry.log().add("Please refer to the calibration instructions");
telemetry.log().add("contained in the Adafruit IMU calibration");
telemetry.log().add("sample opmode.");
telemetry.log().add("");
telemetry.log().add("When sufficient calibration has been reached,");
telemetry.log().add("press the 'A' button to write the current");
telemetry.log().add("calibration data to a file.");
telemetry.log().add("");
// We are expecting the IMU to be attached to an I2C port on a Core Device Interface Module and named "imu".
BNO055IMU.Parameters parameters = new BNO055IMU.Parameters();
parameters.loggingEnabled = true;
parameters.loggingTag = "IMU";
imu = hardwareMap.get(BNO055IMU.class, "imu");
imu.initialize(parameters);
composeTelemetry();
telemetry.log().add("Waiting for start...");
// Wait until we're told to go
while (!isStarted()) {
telemetry.update();
idle();
}
telemetry.log().add("...started...");
while (opModeIsActive()) {
if (gamepad1.a) {
// Get the calibration data
BNO055IMU.CalibrationData calibrationData = imu.readCalibrationData();
// Save the calibration data to a file. You can choose whatever file
// name you wish here, but you'll want to indicate the same file name
// when you initialize the IMU in an opmode in which it is used. If you
// have more than one IMU on your robot, you'll of course want to use
// different configuration file names for each.
String filename = "AdafruitIMUCalibration.json";
File file = AppUtil.getInstance().getSettingsFile(filename);
ReadWriteFile.writeFile(file, calibrationData.serialize());
telemetry.log().add("saved to '%s'", filename);
// Wait for the button to be released
while (gamepad1.a) {
telemetry.update();
idle();
}
}
telemetry.update();
}
}
void composeTelemetry() {
// At the beginning of each telemetry update, grab a bunch of data
// from the IMU that we will then display in separate lines.
telemetry.addAction(new Runnable() { @Override public void run()
{
// Acquiring the angles is relatively expensive; we don't want
// to do that in each of the three items that need that info, as that's
// three times the necessary expense.
angles = imu.getAngularOrientation(AxesReference.INTRINSIC, AxesOrder.ZYX, AngleUnit.DEGREES);
}
});
telemetry.addLine()
.addData("status", new Func() {
@Override public String value() {
return imu.getSystemStatus().toShortString();
}
})
.addData("calib", new Func() {
@Override public String value() {
return imu.getCalibrationStatus().toString();
}
});
telemetry.addLine()
.addData("heading", new Func() {
@Override public String value() {
return formatAngle(angles.angleUnit, angles.firstAngle);
}
})
.addData("roll", new Func() {
@Override public String value() {
return formatAngle(angles.angleUnit, angles.secondAngle);
}
})
.addData("pitch", new Func() {
@Override public String value() {
return formatAngle(angles.angleUnit, angles.thirdAngle);
}
});
}
//----------------------------------------------------------------------------------------------
// Formatting
//----------------------------------------------------------------------------------------------
String formatAngle(AngleUnit angleUnit, double angle) {
return formatDegrees(AngleUnit.DEGREES.fromUnit(angleUnit, angle));
}
String formatDegrees(double degrees){
return String.format(Locale.getDefault(), "%.1f", AngleUnit.DEGREES.normalize(degrees));
}
}
================================================
FILE: FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorColor.java
================================================
/* Copyright (c) 2017 FIRST. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided that
* the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* Neither the name of FIRST nor the names of its contributors may be used to endorse or
* promote products derived from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
* LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.firstinspires.ftc.robotcontroller.external.samples;
import android.app.Activity;
import android.graphics.Color;
import android.view.View;
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.hardware.NormalizedColorSensor;
import com.qualcomm.robotcore.hardware.NormalizedRGBA;
import com.qualcomm.robotcore.hardware.SwitchableLight;
/*
* This is an example LinearOpMode that shows how to use a color sensor in a generic
* way, insensitive which particular make or model of color sensor is used. The opmode
* assumes that the color sensor is configured with a name of "sensor_color".
*
* If the color sensor has a light which is controllable, you can use the X button on
* the gamepad to toggle the light on and off.
*
* Use Android Studio to Copy this Class, and Paste it into your team's code folder with a new name.
* Remove or comment out the @Disabled line to add this opmode to the Driver Station OpMode list
*/
@TeleOp(name = "Sensor: Color", group = "Sensor")
@Disabled
public class SensorColor extends LinearOpMode {
/** The colorSensor field will contain a reference to our color sensor hardware object */
NormalizedColorSensor colorSensor;
/** The relativeLayout field is used to aid in providing interesting visual feedback
* in this sample application; you probably *don't* need something analogous when you
* use a color sensor on your robot */
View relativeLayout;
/**
* The runOpMode() method is the root of this LinearOpMode, as it is in all linear opModes.
* Our implementation here, though is a bit unusual: we've decided to put all the actual work
* in the main() method rather than directly in runOpMode() itself. The reason we do that is that
* in this sample we're changing the background color of the robot controller screen as the
* opmode runs, and we want to be able to *guarantee* that we restore it to something reasonable
* and palatable when the opMode ends. The simplest way to do that is to use a try...finally
* block around the main, core logic, and an easy way to make that all clear was to separate
* the former from the latter in separate methods.
*/
@Override public void runOpMode() throws InterruptedException {
// Get a reference to the RelativeLayout so we can later change the background
// color of the Robot Controller app to match the hue detected by the RGB sensor.
int relativeLayoutId = hardwareMap.appContext.getResources().getIdentifier("RelativeLayout", "id", hardwareMap.appContext.getPackageName());
relativeLayout = ((Activity) hardwareMap.appContext).findViewById(relativeLayoutId);
try {
runSample(); // actually execute the sample
} finally {
// On the way out, *guarantee* that the background is reasonable. It doesn't actually start off
// as pure white, but it's too much work to dig out what actually was used, and this is good
// enough to at least make the screen reasonable again.
// Set the panel back to the default color
relativeLayout.post(new Runnable() {
public void run() {
relativeLayout.setBackgroundColor(Color.WHITE);
}
});
}
}
protected void runSample() throws InterruptedException {
// values is a reference to the hsvValues array.
float[] hsvValues = new float[3];
final float values[] = hsvValues;
// bPrevState and bCurrState keep track of the previous and current state of the button
boolean bPrevState = false;
boolean bCurrState = false;
// Get a reference to our sensor object.
colorSensor = hardwareMap.get(NormalizedColorSensor.class, "sensor_color");
// If possible, turn the light on in the beginning (it might already be on anyway,
// we just make sure it is if we can).
if (colorSensor instanceof SwitchableLight) {
((SwitchableLight)colorSensor).enableLight(true);
}
// Wait for the start button to be pressed.
waitForStart();
// Loop until we are asked to stop
while (opModeIsActive()) {
// Check the status of the x button on the gamepad
bCurrState = gamepad1.x;
// If the button state is different than what it was, then act
if (bCurrState != bPrevState) {
// If the button is (now) down, then toggle the light
if (bCurrState) {
if (colorSensor instanceof SwitchableLight) {
SwitchableLight light = (SwitchableLight)colorSensor;
light.enableLight(!light.isLightOn());
}
}
}
bPrevState = bCurrState;
// Read the sensor
NormalizedRGBA colors = colorSensor.getNormalizedColors();
/** Use telemetry to display feedback on the driver station. We show the conversion
* of the colors to hue, saturation and value, and display the the normalized values
* as returned from the sensor.
* @see HSV*/
Color.colorToHSV(colors.toColor(), hsvValues);
telemetry.addLine()
.addData("H", "%.3f", hsvValues[0])
.addData("S", "%.3f", hsvValues[1])
.addData("V", "%.3f", hsvValues[2]);
telemetry.addLine()
.addData("a", "%.3f", colors.alpha)
.addData("r", "%.3f", colors.red)
.addData("g", "%.3f", colors.green)
.addData("b", "%.3f", colors.blue);
/** We also display a conversion of the colors to an equivalent Android color integer.
* @see Color */
int color = colors.toColor();
telemetry.addLine("raw Android color: ")
.addData("a", "%02x", Color.alpha(color))
.addData("r", "%02x", Color.red(color))
.addData("g", "%02x", Color.green(color))
.addData("b", "%02x", Color.blue(color));
// Balance the colors. The values returned by getColors() are normalized relative to the
// maximum possible values that the sensor can measure. For example, a sensor might in a
// particular configuration be able to internally measure color intensity in a range of
// [0, 10240]. In such a case, the values returned by getColors() will be divided by 10240
// so as to return a value it the range [0,1]. However, and this is the point, even so, the
// values we see here may not get close to 1.0 in, e.g., low light conditions where the
// sensor measurements don't approach their maximum limit. In such situations, the *relative*
// intensities of the colors are likely what is most interesting. Here, for example, we boost
// the signal on the colors while maintaining their relative balance so as to give more
// vibrant visual feedback on the robot controller visual display.
float max = Math.max(Math.max(Math.max(colors.red, colors.green), colors.blue), colors.alpha);
colors.red /= max;
colors.green /= max;
colors.blue /= max;
color = colors.toColor();
telemetry.addLine("normalized color: ")
.addData("a", "%02x", Color.alpha(color))
.addData("r", "%02x", Color.red(color))
.addData("g", "%02x", Color.green(color))
.addData("b", "%02x", Color.blue(color));
telemetry.update();
// convert the RGB values to HSV values.
Color.RGBToHSV(Color.red(color), Color.green(color), Color.blue(color), hsvValues);
// change the background color to match the color detected by the RGB sensor.
// pass a reference to the hue, saturation, and value array as an argument
// to the HSVToColor method.
relativeLayout.post(new Runnable() {
public void run() {
relativeLayout.setBackgroundColor(Color.HSVToColor(0xff, values));
}
});
}
}
}
================================================
FILE: FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorDIO.java
================================================
/* Copyright (c) 2017 FIRST. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided that
* the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* Neither the name of FIRST nor the names of its contributors may be used to endorse or
* promote products derived from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
* LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.firstinspires.ftc.robotcontroller.external.samples;
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.hardware.DeviceInterfaceModule;
import com.qualcomm.robotcore.hardware.DigitalChannel;
/*
* This is an example LinearOpMode that shows how to use the digital inputs and outputs on the
* the Modern Robotics Device Interface Module. In addition, it shows how to use the Red and Blue LED
*
* This op mode assumes that there is a Device Interface Module attached, named 'dim'.
* On this DIM there is a digital input named 'digin' and an output named 'digout'
*
* To fully exercise this sample, connect pin 3 of the digin connector to pin 3 of the digout.
* Note: Pin 1 is indicated by the black stripe, so pin 3 is at the opposite end.
*
* The X button on the gamepad will be used to activate the digital output pin.
* The Red/Blue LED will be used to indicate the state of the digital input pin.
* Blue = false (0V), Red = true (5V)
* If the two pins are linked, the gamepad will change the LED color.
*
* Use Android Studio to Copy this Class, and Paste it into your team's code folder with a new name.
* Remove or comment out the @Disabled line to add this opmode to the Driver Station OpMode list
*/
@TeleOp(name = "Sensor: DIM DIO", group = "Sensor")
@Disabled
public class SensorDIO extends LinearOpMode {
final int BLUE_LED_CHANNEL = 0;
final int RED_LED_CHANNEL = 1;
@Override
public void runOpMode() {
boolean inputPin; // Input State
boolean outputPin; // Output State
DeviceInterfaceModule dim; // Device Object
DigitalChannel digIn; // Device Object
DigitalChannel digOut; // Device Object
// get a reference to a Modern Robotics DIM, and IO channels.
dim = hardwareMap.get(DeviceInterfaceModule.class, "dim"); // Use generic form of device mapping
digIn = hardwareMap.get(DigitalChannel.class, "digin"); // Use generic form of device mapping
digOut = hardwareMap.get(DigitalChannel.class, "digout"); // Use generic form of device mapping
digIn.setMode(DigitalChannel.Mode.INPUT); // Set the direction of each channel
digOut.setMode(DigitalChannel.Mode.OUTPUT);
// wait for the start button to be pressed.
telemetry.addData(">", "Press play, and then user X button to set DigOut");
telemetry.update();
waitForStart();
while (opModeIsActive()) {
outputPin = gamepad1.x ; // Set the output pin based on x button
digOut.setState(outputPin);
inputPin = digIn.getState(); // Read the input pin
// Display input pin state on LEDs
if (inputPin) {
dim.setLED(RED_LED_CHANNEL, true);
dim.setLED(BLUE_LED_CHANNEL, false);
}
else {
dim.setLED(RED_LED_CHANNEL, false);
dim.setLED(BLUE_LED_CHANNEL, true);
}
telemetry.addData("Output", outputPin );
telemetry.addData("Input", inputPin );
telemetry.addData("LED", inputPin ? "Red" : "Blue" );
telemetry.update();
}
}
}
================================================
FILE: FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorDigitalTouch.java
================================================
/* Copyright (c) 2017 FIRST. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided that
* the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* Neither the name of FIRST nor the names of its contributors may be used to endorse or
* promote products derived from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
* LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.firstinspires.ftc.robotcontroller.external.samples;
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.hardware.DigitalChannel;
/*
* This is an example LinearOpMode that shows how to use
* a REV Robotics Touch Sensor.
*
* It assumes that the touch sensor is configured with a name of "sensor_digital".
*
* Use Android Studio to Copy this Class, and Paste it into your team's code folder with a new name.
* Remove or comment out the @Disabled line to add this opmode to the Driver Station OpMode list.
*/
@TeleOp(name = "Sensor: Digital touch", group = "Sensor")
@Disabled
public class SensorDigitalTouch extends LinearOpMode {
/**
* The REV Robotics Touch Sensor
* is treated as a digital channel. It is HIGH if the button is unpressed.
* It pulls LOW if the button is pressed.
*
* Also, when you connect a REV Robotics Touch Sensor to the digital I/O port on the
* Expansion Hub using a 4-wire JST cable, the second pin gets connected to the Touch Sensor.
* The lower (first) pin stays unconnected.*
*/
DigitalChannel digitalTouch; // Hardware Device Object
@Override
public void runOpMode() {
// get a reference to our digitalTouch object.
digitalTouch = hardwareMap.get(DigitalChannel.class, "sensor_digital");
// set the digital channel to input.
digitalTouch.setMode(DigitalChannel.Mode.INPUT);
// wait for the start button to be pressed.
waitForStart();
// while the op mode is active, loop and read the light levels.
// Note we use opModeIsActive() as our loop condition because it is an interruptible method.
while (opModeIsActive()) {
// send the info back to driver station using telemetry function.
// if the digital channel returns true it's HIGH and the button is unpressed.
if (digitalTouch.getState() == true) {
telemetry.addData("Digital Touch", "Is Not Pressed");
} else {
telemetry.addData("Digital Touch", "Is Pressed");
}
telemetry.update();
}
}
}
================================================
FILE: FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorKLNavxMicro.java
================================================
/* Copyright (c) 2017 FIRST. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided that
* the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* Neither the name of FIRST nor the names of its contributors may be used to endorse or
* promote products derived from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
* LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.firstinspires.ftc.robotcontroller.external.samples;
import com.qualcomm.hardware.kauailabs.NavxMicroNavigationSensor;
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.hardware.Gyroscope;
import com.qualcomm.robotcore.hardware.IntegratingGyroscope;
import com.qualcomm.robotcore.util.ElapsedTime;
import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
import org.firstinspires.ftc.robotcore.external.navigation.AngularVelocity;
import org.firstinspires.ftc.robotcore.external.navigation.AxesOrder;
import org.firstinspires.ftc.robotcore.external.navigation.AxesReference;
import org.firstinspires.ftc.robotcore.external.navigation.Orientation;
/*
* This is an example LinearOpMode that shows how to use Kauai Labs navX Micro Robotics Navigation
* Sensor. It assumes that the sensor is configured with a name of "navx".
*
* Use Android Studio to Copy this Class, and Paste it into your team's code folder with a new name.
* Remove or comment out the @Disabled line to add this opmode to the Driver Station OpMode list
*/
@TeleOp(name = "Sensor: KL navX Micro", group = "Sensor")
@Disabled
public class SensorKLNavxMicro extends LinearOpMode {
/** In this sample, for illustration purposes we use two interfaces on the one gyro object.
* That's likely atypical: you'll probably use one or the other in any given situation,
* depending on what you're trying to do. {@link IntegratingGyroscope} (and it's base interface,
* {@link Gyroscope}) are common interfaces supported by possibly several different gyro
* implementations. {@link NavxMicroNavigationSensor}, by contrast, provides functionality that
* is unique to the navX Micro sensor.
*/
IntegratingGyroscope gyro;
NavxMicroNavigationSensor navxMicro;
// A timer helps provide feedback while calibration is taking place
ElapsedTime timer = new ElapsedTime();
@Override public void runOpMode() throws InterruptedException {
// Get a reference to a Modern Robotics GyroSensor object. We use several interfaces
// on this object to illustrate which interfaces support which functionality.
navxMicro = hardwareMap.get(NavxMicroNavigationSensor.class, "navx");
gyro = (IntegratingGyroscope)navxMicro;
// If you're only interested int the IntegratingGyroscope interface, the following will suffice.
// gyro = hardwareMap.get(IntegratingGyroscope.class, "navx");
// The gyro automatically starts calibrating. This takes a few seconds.
telemetry.log().add("Gyro Calibrating. Do Not Move!");
// Wait until the gyro calibration is complete
timer.reset();
while (navxMicro.isCalibrating()) {
telemetry.addData("calibrating", "%s", Math.round(timer.seconds())%2==0 ? "|.." : "..|");
telemetry.update();
Thread.sleep(50);
}
telemetry.log().clear(); telemetry.log().add("Gyro Calibrated. Press Start.");
telemetry.clear(); telemetry.update();
// Wait for the start button to be pressed
waitForStart();
telemetry.log().clear();
while (opModeIsActive()) {
// Read dimensionalized data from the gyro. This gyro can report angular velocities
// about all three axes. Additionally, it internally integrates the Z axis to
// be able to report an absolute angular Z orientation.
AngularVelocity rates = gyro.getAngularVelocity(AngleUnit.DEGREES);
Orientation angles = gyro.getAngularOrientation(AxesReference.INTRINSIC, AxesOrder.ZYX, AngleUnit.DEGREES);
telemetry.addLine()
.addData("dx", formatRate(rates.xRotationRate))
.addData("dy", formatRate(rates.yRotationRate))
.addData("dz", "%s deg/s", formatRate(rates.zRotationRate));
telemetry.addLine()
.addData("heading", formatAngle(angles.angleUnit, angles.firstAngle))
.addData("roll", formatAngle(angles.angleUnit, angles.secondAngle))
.addData("pitch", "%s deg", formatAngle(angles.angleUnit, angles.thirdAngle));
telemetry.update();
idle(); // Always call idle() at the bottom of your while(opModeIsActive()) loop
}
}
String formatRate(float rate) {
return String.format("%.3f", rate);
}
String formatAngle(AngleUnit angleUnit, double angle) {
return formatDegrees(AngleUnit.DEGREES.fromUnit(angleUnit, angle));
}
String formatDegrees(double degrees){
return String.format("%.1f", AngleUnit.DEGREES.normalize(degrees));
}
}
================================================
FILE: FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRColor.java
================================================
/* Copyright (c) 2017 FIRST. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided that
* the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* Neither the name of FIRST nor the names of its contributors may be used to endorse or
* promote products derived from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
* LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.firstinspires.ftc.robotcontroller.external.samples;
import android.app.Activity;
import android.graphics.Color;
import android.view.View;
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.hardware.ColorSensor;
/*
*
* This is an example LinearOpMode that shows how to use
* a Modern Robotics Color Sensor.
*
* The op mode assumes that the color sensor
* is configured with a name of "sensor_color".
*
* You can use the X button on gamepad1 to toggle the LED on and off.
*
* Use Android Studio to Copy this Class, and Paste it into your team's code folder with a new name.
* Remove or comment out the @Disabled line to add this opmode to the Driver Station OpMode list
*/
@TeleOp(name = "Sensor: MR Color", group = "Sensor")
@Disabled
public class SensorMRColor extends LinearOpMode {
ColorSensor colorSensor; // Hardware Device Object
@Override
public void runOpMode() {
// hsvValues is an array that will hold the hue, saturation, and value information.
float hsvValues[] = {0F,0F,0F};
// values is a reference to the hsvValues array.
final float values[] = hsvValues;
// get a reference to the RelativeLayout so we can change the background
// color of the Robot Controller app to match the hue detected by the RGB sensor.
int relativeLayoutId = hardwareMap.appContext.getResources().getIdentifier("RelativeLayout", "id", hardwareMap.appContext.getPackageName());
final View relativeLayout = ((Activity) hardwareMap.appContext).findViewById(relativeLayoutId);
// bPrevState and bCurrState represent the previous and current state of the button.
boolean bPrevState = false;
boolean bCurrState = false;
// bLedOn represents the state of the LED.
boolean bLedOn = true;
// get a reference to our ColorSensor object.
colorSensor = hardwareMap.get(ColorSensor.class, "sensor_color");
// Set the LED in the beginning
colorSensor.enableLed(bLedOn);
// wait for the start button to be pressed.
waitForStart();
// while the op mode is active, loop and read the RGB data.
// Note we use opModeIsActive() as our loop condition because it is an interruptible method.
while (opModeIsActive()) {
// check the status of the x button on either gamepad.
bCurrState = gamepad1.x;
// check for button state transitions.
if (bCurrState && (bCurrState != bPrevState)) {
// button is transitioning to a pressed state. So Toggle LED
bLedOn = !bLedOn;
colorSensor.enableLed(bLedOn);
}
// update previous state variable.
bPrevState = bCurrState;
// convert the RGB values to HSV values.
Color.RGBToHSV(colorSensor.red() * 8, colorSensor.green() * 8, colorSensor.blue() * 8, hsvValues);
// send the info back to driver station using telemetry function.
telemetry.addData("LED", bLedOn ? "On" : "Off");
telemetry.addData("Clear", colorSensor.alpha());
telemetry.addData("Red ", colorSensor.red());
telemetry.addData("Green", colorSensor.green());
telemetry.addData("Blue ", colorSensor.blue());
telemetry.addData("Hue", hsvValues[0]);
// change the background color to match the color detected by the RGB sensor.
// pass a reference to the hue, saturation, and value array as an argument
// to the HSVToColor method.
relativeLayout.post(new Runnable() {
public void run() {
relativeLayout.setBackgroundColor(Color.HSVToColor(0xff, values));
}
});
telemetry.update();
}
// Set the panel back to the default color
relativeLayout.post(new Runnable() {
public void run() {
relativeLayout.setBackgroundColor(Color.WHITE);
}
});
}
}
================================================
FILE: FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRCompass.java
================================================
/* Copyright (c) 2017 FIRST. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided that
* the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* Neither the name of FIRST nor the names of its contributors may be used to endorse or
* promote products derived from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
* LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.firstinspires.ftc.robotcontroller.external.samples;
import com.qualcomm.hardware.modernrobotics.ModernRoboticsI2cCompassSensor;
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;
import org.firstinspires.ftc.robotcore.external.navigation.Acceleration;
/**
* The {@link SensorMRCompass} op mode provides a demonstration of the
* functionality provided by the Modern Robotics compass sensor.
*
* The op mode assumes that the MR compass is configured with a name of "compass".
*
* Use Android Studio to Copy this Class, and Paste it into your team's code folder with a new name.
* Remove or comment out the @Disabled line to add this opmode to the Driver Station OpMode list
*
* @see MR Compass Sensor
*/
@TeleOp(name = "Sensor: MR compass", group = "Sensor")
@Disabled // comment out or remove this line to enable this opmode
public class SensorMRCompass extends LinearOpMode {
ModernRoboticsI2cCompassSensor compass;
ElapsedTime timer = new ElapsedTime();
@Override public void runOpMode() {
// get a reference to our compass
compass = hardwareMap.get(ModernRoboticsI2cCompassSensor.class, "compass");
telemetry.log().setCapacity(20);
telemetry.log().add("The compass sensor operates quite well out-of-the");
telemetry.log().add("box, as shipped by the manufacturer. Precision can");
telemetry.log().add("however be somewhat improved with calibration.");
telemetry.log().add("");
telemetry.log().add("To calibrate the compass once the opmode is");
telemetry.log().add("started, make sure the compass is level, then");
telemetry.log().add("press 'A' on the gamepad. Next, slowly rotate the ");
telemetry.log().add("compass in a full 360 degree circle while keeping");
telemetry.log().add("it level. When complete, press 'B'.");
// wait for the start button to be pressed
waitForStart();
telemetry.log().clear();
while (opModeIsActive()) {
// If the A button is pressed, start calibration and wait for the A button to rise
if (gamepad1.a && !compass.isCalibrating()) {
telemetry.log().clear();
telemetry.log().add("Calibration started");
telemetry.log().add("Slowly rotate compass 360deg");
telemetry.log().add("Press 'B' when complete");
compass.setMode(CompassSensor.CompassMode.CALIBRATION_MODE);
timer.reset();
while (gamepad1.a && opModeIsActive()) {
doTelemetry();
idle();
}
}
// If the B button is pressed, stop calibration and wait for the B button to rise
if (gamepad1.b && compass.isCalibrating()) {
telemetry.log().clear();
telemetry.log().add("Calibration complete");
compass.setMode(CompassSensor.CompassMode.MEASUREMENT_MODE);
if (compass.calibrationFailed()) {
telemetry.log().add("Calibration failed");
compass.writeCommand(ModernRoboticsI2cCompassSensor.Command.NORMAL);
}
while (gamepad1.a && opModeIsActive()) {
doTelemetry();
idle();
}
}
doTelemetry();
}
}
protected void doTelemetry() {
if (compass.isCalibrating()) {
telemetry.addData("compass", "calibrating %s", Math.round(timer.seconds())%2==0 ? "|.." : "..|");
} else {
// getDirection() returns a traditional compass heading in the range [0,360),
// with values increasing in a CW direction
telemetry.addData("heading", "%.1f", compass.getDirection());
// getAcceleration() returns the current 3D acceleration experienced by
// the sensor. This is used internally to the sensor to compute its tilt and thence
// to correct the magnetometer reading to produce tilt-corrected values in getDirection()
Acceleration accel = compass.getAcceleration();
double accelMagnitude = Math.sqrt(accel.xAccel*accel.xAccel + accel.yAccel*accel.yAccel + accel.zAccel*accel.zAccel);
telemetry.addData("accel", accel);
telemetry.addData("accel magnitude", "%.3f", accelMagnitude);
// getMagneticFlux returns the 3D magnetic field flux experienced by the sensor
telemetry.addData("mag flux", compass.getMagneticFlux());
}
// the command register provides status data
telemetry.addData("command", "%s", compass.readCommand());
telemetry.update();
}
}
================================================
FILE: FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRGyro.java
================================================
/* Copyright (c) 2017 FIRST. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided that
* the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* Neither the name of FIRST nor the names of its contributors may be used to endorse or
* promote products derived from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
* LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.firstinspires.ftc.robotcontroller.external.samples;
import com.qualcomm.hardware.modernrobotics.ModernRoboticsI2cGyro;
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.hardware.Gyroscope;
import com.qualcomm.robotcore.hardware.IntegratingGyroscope;
import com.qualcomm.robotcore.util.ElapsedTime;
import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
import org.firstinspires.ftc.robotcore.external.navigation.AngularVelocity;
import org.firstinspires.ftc.robotcore.external.navigation.AxesOrder;
import org.firstinspires.ftc.robotcore.external.navigation.AxesReference;
/*
* This is an example LinearOpMode that shows how to use the Modern Robotics Gyro.
*
* The op mode assumes that the gyro sensor is attached to a Device Interface Module
* I2C channel and is configured with a name of "gyro".
*
* Use Android Studio to Copy this Class, and Paste it into your team's code folder with a new name.
* Remove or comment out the @Disabled line to add this opmode to the Driver Station OpMode list
*/
@TeleOp(name = "Sensor: MR Gyro", group = "Sensor")
@Disabled
public class SensorMRGyro extends LinearOpMode {
/** In this sample, for illustration purposes we use two interfaces on the one gyro object.
* That's likely atypical: you'll probably use one or the other in any given situation,
* depending on what you're trying to do. {@link IntegratingGyroscope} (and it's base interface,
* {@link Gyroscope}) are common interfaces supported by possibly several different gyro
* implementations. {@link ModernRoboticsI2cGyro}, by contrast, provides functionality that
* is unique to the Modern Robotics gyro sensor.
*/
IntegratingGyroscope gyro;
ModernRoboticsI2cGyro modernRoboticsI2cGyro;
// A timer helps provide feedback while calibration is taking place
ElapsedTime timer = new ElapsedTime();
@Override
public void runOpMode() {
boolean lastResetState = false;
boolean curResetState = false;
// Get a reference to a Modern Robotics gyro object. We use several interfaces
// on this object to illustrate which interfaces support which functionality.
modernRoboticsI2cGyro = hardwareMap.get(ModernRoboticsI2cGyro.class, "gyro");
gyro = (IntegratingGyroscope)modernRoboticsI2cGyro;
// If you're only interested int the IntegratingGyroscope interface, the following will suffice.
// gyro = hardwareMap.get(IntegratingGyroscope.class, "gyro");
// A similar approach will work for the Gyroscope interface, if that's all you need.
// Start calibrating the gyro. This takes a few seconds and is worth performing
// during the initialization phase at the start of each opMode.
telemetry.log().add("Gyro Calibrating. Do Not Move!");
modernRoboticsI2cGyro.calibrate();
// Wait until the gyro calibration is complete
timer.reset();
while (!isStopRequested() && modernRoboticsI2cGyro.isCalibrating()) {
telemetry.addData("calibrating", "%s", Math.round(timer.seconds())%2==0 ? "|.." : "..|");
telemetry.update();
sleep(50);
}
telemetry.log().clear(); telemetry.log().add("Gyro Calibrated. Press Start.");
telemetry.clear(); telemetry.update();
// Wait for the start button to be pressed
waitForStart();
telemetry.log().clear();
telemetry.log().add("Press A & B to reset heading");
// Loop until we're asked to stop
while (opModeIsActive()) {
// If the A and B buttons are pressed just now, reset Z heading.
curResetState = (gamepad1.a && gamepad1.b);
if (curResetState && !lastResetState) {
modernRoboticsI2cGyro.resetZAxisIntegrator();
}
lastResetState = curResetState;
// The raw() methods report the angular rate of change about each of the
// three axes directly as reported by the underlying sensor IC.
int rawX = modernRoboticsI2cGyro.rawX();
int rawY = modernRoboticsI2cGyro.rawY();
int rawZ = modernRoboticsI2cGyro.rawZ();
int heading = modernRoboticsI2cGyro.getHeading();
int integratedZ = modernRoboticsI2cGyro.getIntegratedZValue();
// Read dimensionalized data from the gyro. This gyro can report angular velocities
// about all three axes. Additionally, it internally integrates the Z axis to
// be able to report an absolute angular Z orientation.
AngularVelocity rates = gyro.getAngularVelocity(AngleUnit.DEGREES);
float zAngle = gyro.getAngularOrientation(AxesReference.INTRINSIC, AxesOrder.ZYX, AngleUnit.DEGREES).firstAngle;
// Read administrative information from the gyro
int zAxisOffset = modernRoboticsI2cGyro.getZAxisOffset();
int zAxisScalingCoefficient = modernRoboticsI2cGyro.getZAxisScalingCoefficient();
telemetry.addLine()
.addData("dx", formatRate(rates.xRotationRate))
.addData("dy", formatRate(rates.yRotationRate))
.addData("dz", "%s deg/s", formatRate(rates.zRotationRate));
telemetry.addData("angle", "%s deg", formatFloat(zAngle));
telemetry.addData("heading", "%3d deg", heading);
telemetry.addData("integrated Z", "%3d", integratedZ);
telemetry.addLine()
.addData("rawX", formatRaw(rawX))
.addData("rawY", formatRaw(rawY))
.addData("rawZ", formatRaw(rawZ));
telemetry.addLine().addData("z offset", zAxisOffset).addData("z coeff", zAxisScalingCoefficient);
telemetry.update();
}
}
String formatRaw(int rawValue) {
return String.format("%d", rawValue);
}
String formatRate(float rate) {
return String.format("%.3f", rate);
}
String formatFloat(float rate) {
return String.format("%.3f", rate);
}
}
================================================
FILE: FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRIrSeeker.java
================================================
/* Copyright (c) 2017 FIRST. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided that
* the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* Neither the name of FIRST nor the names of its contributors may be used to endorse or
* promote products derived from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
* LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.firstinspires.ftc.robotcontroller.external.samples;
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.hardware.IrSeekerSensor;
/*
* This is an example LinearOpMode that shows how to use
* the Modern Robotics ITR Seeker
*
* The op mode assumes that the IR Seeker
* is configured with a name of "sensor_ir".
*
* Set the switch on the Modern Robotics IR beacon to 1200 at 180.
* Turn on the IR beacon.
* Make sure the side of the beacon with the LED on is facing the robot.
*
* Use Android Studio to Copy this Class, and Paste it into your team's code folder with a new name.
* Remove or comment out the @Disabled line to add this opmode to the Driver Station OpMode list
*/
@TeleOp(name = "Sensor: MR IR Seeker", group = "Sensor")
@Disabled
public class SensorMRIrSeeker extends LinearOpMode {
@Override
public void runOpMode() {
IrSeekerSensor irSeeker; // Hardware Device Object
// get a reference to our GyroSensor object.
irSeeker = hardwareMap.get(IrSeekerSensor.class, "sensor_ir");
// wait for the start button to be pressed.
waitForStart();
while (opModeIsActive()) {
// Ensure we have a IR signal
if (irSeeker.signalDetected())
{
// Display angle and strength
telemetry.addData("Angle", irSeeker.getAngle());
telemetry.addData("Strength", irSeeker.getStrength());
}
else
{
// Display loss of signal
telemetry.addData("Seeker", "Signal Lost");
}
telemetry.update();
}
}
}
================================================
FILE: FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMROpticalDistance.java
================================================
/* Copyright (c) 2017 FIRST. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided that
* the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* Neither the name of FIRST nor the names of its contributors may be used to endorse or
* promote products derived from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
* LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.firstinspires.ftc.robotcontroller.external.samples;
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.hardware.OpticalDistanceSensor;
/*
* This is an example LinearOpMode that shows how to use
* a Modern Robotics Optical Distance Sensor
* It assumes that the ODS sensor is configured with a name of "sensor_ods".
*
* Use Android Studio to Copy this Class, and Paste it into your team's code folder with a new name.
* Remove or comment out the @Disabled line to add this opmode to the Driver Station OpMode list
*/
@TeleOp(name = "Sensor: MR ODS", group = "Sensor")
@Disabled
public class SensorMROpticalDistance extends LinearOpMode {
OpticalDistanceSensor odsSensor; // Hardware Device Object
@Override
public void runOpMode() {
// get a reference to our Light Sensor object.
odsSensor = hardwareMap.get(OpticalDistanceSensor.class, "sensor_ods");
// wait for the start button to be pressed.
waitForStart();
// while the op mode is active, loop and read the light levels.
// Note we use opModeIsActive() as our loop condition because it is an interruptible method.
while (opModeIsActive()) {
// send the info back to driver station using telemetry function.
telemetry.addData("Raw", odsSensor.getRawLightDetected());
telemetry.addData("Normal", odsSensor.getLightDetected());
telemetry.update();
}
}
}
================================================
FILE: FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorMRRangeSensor.java
================================================
/* Copyright (c) 2017 FIRST. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided that
* the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* Neither the name of FIRST nor the names of its contributors may be used to endorse or
* promote products derived from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
* LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.firstinspires.ftc.robotcontroller.external.samples;
import com.qualcomm.hardware.modernrobotics.ModernRoboticsI2cRangeSensor;
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit;
/**
* {@link SensorMRRangeSensor} illustrates how to use the Modern Robotics
* 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 MR Range Sensor
*/
@TeleOp(name = "Sensor: MR range sensor", group = "Sensor")
@Disabled // comment out or remove this line to enable this opmode
public class SensorMRRangeSensor extends LinearOpMode {
ModernRoboticsI2cRangeSensor rangeSensor;
@Override public void runOpMode() {
// get a reference to our compass
rangeSensor = hardwareMap.get(ModernRoboticsI2cRangeSensor.class, "sensor_range");
// wait for the start button to be pressed
waitForStart();
while (opModeIsActive()) {
telemetry.addData("raw ultrasonic", rangeSensor.rawUltrasonic());
telemetry.addData("raw optical", rangeSensor.rawOptical());
telemetry.addData("cm optical", "%.2f cm", rangeSensor.cmOptical());
telemetry.addData("cm", "%.2f cm", rangeSensor.getDistance(DistanceUnit.CM));
telemetry.update();
}
}
}
================================================
FILE: FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorREV2mDistance.java
================================================
/*
Copyright (c) 2018 FIRST
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted (subject to the limitations in the disclaimer below) provided that
the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
Neither the name of FIRST nor the names of its contributors may be used to
endorse or promote products derived from this software without specific prior
written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.firstinspires.ftc.robotcontroller.external.samples;
import com.qualcomm.hardware.rev.Rev2mDistanceSensor;
import com.qualcomm.robotcore.eventloop.opmode.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();
}
}
}
================================================
FILE: FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/SensorREVColorDistance.java
================================================
/* Copyright (c) 2017 FIRST. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided that
* the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* Neither the name of FIRST nor the names of its contributors may be used to endorse or
* promote products derived from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
* LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.firstinspires.ftc.robotcontroller.external.samples;
import android.app.Activity;
import android.graphics.Color;
import android.view.View;
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.hardware.ColorSensor;
import com.qualcomm.robotcore.hardware.DistanceSensor;
import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit;
import java.util.Locale;
/*
* This is an example LinearOpMode that shows how to use
* the REV Robotics Color-Distance Sensor.
*
* It assumes the sensor is configured with the name "sensor_color_distance".
*
* Use Android Studio to Copy this Class, and Paste it into your team's code folder with a new name.
* Remove or comment out the @Disabled line to add this opmode to the Driver Station OpMode list.
*/
@TeleOp(name = "Sensor: REVColorDistance", group = "Sensor")
@Disabled // Comment this out to add to the opmode list
public class SensorREVColorDistance extends LinearOpMode {
/**
* Note that the REV Robotics Color-Distance incorporates two sensors into one device.
* It has an IR proximity sensor which is used to calculate distance and an RGB color sensor.
*
* There will be some variation in the values measured depending on whether you are using a
* V3 color sensor versus the older V2 and V1 sensors, as the V3 is based around a different chip.
*
* For V1/V2, the light/distance sensor saturates at around 2" (5cm). This means that targets that are 2"
* or closer will display the same value for distance/light detected.
*
* For V3, the distance sensor as configured can handle distances between 0.25" (~0.6cm) and 6" (~15cm).
* Any target closer than 0.25" will dislay as 0.25" and any target farther than 6" will display as 6".
*
* Note that the distance sensor function of both chips is built around an IR proximity sensor, which is
* sensitive to ambient light and the reflectivity of the surface against which you are measuring. If
* very accurate distance is required you should consider calibrating the raw optical values read from the
* chip to your exact situation.
*
* Although you configure a single REV Robotics Color-Distance sensor in your configuration file,
* you can treat the sensor as two separate sensors that share the same name in your op mode.
*
* In this example, we represent the detected color by a hue, saturation, and value color
* model (see https://en.wikipedia.org/wiki/HSL_and_HSV). We change the background
* color of the screen to match the detected color.
*
* In this example, we also use the distance sensor to display the distance
* to the target object.
*
*/
ColorSensor sensorColor;
DistanceSensor sensorDistance;
@Override
public void runOpMode() {
// get a reference to the color sensor.
sensorColor = hardwareMap.get(ColorSensor.class, "sensor_color_distance");
// get a reference to the distance sensor that shares the same name.
sensorDistance = hardwareMap.get(DistanceSensor.class, "sensor_color_distance");
// hsvValues is an array that will hold the hue, saturation, and value information.
float hsvValues[] = {0F, 0F, 0F};
// values is a reference to the hsvValues array.
final float values[] = hsvValues;
// sometimes it helps to multiply the raw RGB values with a scale factor
// to amplify/attentuate the measured values.
final double SCALE_FACTOR = 255;
// get a reference to the RelativeLayout so we can change the background
// color of the Robot Controller app to match the hue detected by the RGB sensor.
int relativeLayoutId = hardwareMap.appContext.getResources().getIdentifier("RelativeLayout", "id", hardwareMap.appContext.getPackageName());
final View relativeLayout = ((Activity) hardwareMap.appContext).findViewById(relativeLayoutId);
// wait for the start button to be pressed.
waitForStart();
// loop and read the RGB and distance data.
// Note we use opModeIsActive() as our loop condition because it is an interruptible method.
while (opModeIsActive()) {
// convert the RGB values to HSV values.
// multiply by the SCALE_FACTOR.
// then cast it back to int (SCALE_FACTOR is a double)
Color.RGBToHSV((int) (sensorColor.red() * SCALE_FACTOR),
(int) (sensorColor.green() * SCALE_FACTOR),
(int) (sensorColor.blue() * SCALE_FACTOR),
hsvValues);
// send the info back to driver station using telemetry function.
telemetry.addData("Distance (cm)",
String.format(Locale.US, "%.02f", sensorDistance.getDistance(DistanceUnit.CM)));
telemetry.addData("Alpha", sensorColor.alpha());
telemetry.addData("Red ", sensorColor.red());
telemetry.addData("Green", sensorColor.green());
telemetry.addData("Blue ", sensorColor.blue());
telemetry.addData("Hue", hsvValues[0]);
// change the background color to match the color detected by the RGB sensor.
// pass a reference to the hue, saturation, and value array as an argument
// to the HSVToColor method.
relativeLayout.post(new Runnable() {
public void run() {
relativeLayout.setBackgroundColor(Color.HSVToColor(0xff, values));
}
});
telemetry.update();
}
// Set the panel back to the default color
relativeLayout.post(new Runnable() {
public void run() {
relativeLayout.setBackgroundColor(Color.WHITE);
}
});
}
}
================================================
FILE: FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/readme.md
================================================
## Caution
No Team-specific code should be placed or modified in this ``.../samples`` folder.
Full or partial Samples should be Copied from here, and then Pasted into
the team's folder, using the Android Studio cut and paste commands.
This automatically changes all file and class names to be consistent.
### Naming of Samples
To gain a better understanding of how the samples are organized, and how to interpret the
naming system, it will help to understand the conventions that were used during their creation.
These conventions are described (in detail) in the sample_conventions.md file in this folder.
To summarize: A range of different samples classes will reside in the java/external/samples.
The class names will follow a naming convention which indicates the purpose of each class.
The prefix of the name will be one of the following:
Basic: This is a minimally functional OpMode used to illustrate the skeleton/structure
of a particular style of OpMode. These are bare bones examples.
Sensor: This is a Sample OpMode that shows how to use a specific sensor.
It is not intended to drive a functioning robot, it is simply showing the minimal code
required to read and display the sensor values.
Hardware: This is NOT an OpMode, but a helper class that is used to describe
one particular robot's hardware configuration: eg: For the K9 or Pushbot.
Look at any Pushbot sample to see how this can be used in an OpMode.
Teams can copy one of these to their team folder to create their own robot definition.
Pushbot: This is a Sample OpMode that uses the Pushbot robot hardware as a base.
It may be used to provide some standard baseline Pushbot OpModes, or
to demonstrate how a particular sensor or concept can be used directly on the
Pushbot chassis.
Concept: This is a sample OpMode that illustrates performing a specific function or concept.
These may be complex, but their operation should be explained clearly in the comments,
or the comments should reference an external doc, guide or tutorial.
Each OpMode should try to only demonstrate a single concept so they are easy to
locate based on their name. These OpModes may not produce a drivable robot.
Library: This is a class, or set of classes used to implement some strategy.
These will typically NOT implement a full OpMode. Instead they will be included
by an OpMode to provide some stand-alone capability.
After the prefix, other conventions will apply:
* Sensor class names are constructed as: Sensor - Company - Type
* Hardware class names are constructed as: Hardware - Robot type
* Pushbot class names are constructed as: Pushbot - Mode - Action - OpModetype
* Concept class names are constructed as: Concept - Topic - OpModetype
* Library class names are constructed as: Library - Topic - OpModetype
================================================
FILE: FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/sample_conventions.md
================================================
## Sample Class/Opmode conventions
#### V 1.1.0 8/9/2017
This document defines the FTC Sample OpMode and Class conventions.
### OpMode Name
A range of different samples classes will reside in the java/external/samples folder.
For ease of understanding, the class names will follow a naming convention which indicates
the purpose of each class. The prefix of the name will be one of the following:
Basic: This is a minimally functional OpMode used to illustrate the skeleton/structure
of a particular style of OpMode. These are bare bones Tank Drive examples.
Sensor: This is a Sample OpMode that shows how to use a specific sensor.
It is not intended to drive a functioning robot, it is simply showing the minimal code
required to read and display the sensor values.
Hardware: This is not an actual OpMode, but a helper class that is used to describe
one particular robot's hardware configuration: eg: For the K9 or Pushbot.
Look at any Pushbot sample to see how this can be used in an OpMode.
Teams can copy one of these to create their own robot definition.
Pushbot: This is a Sample OpMode that uses the Pushbot robot hardware as a base.
It may be used to provide some standard baseline Pushbot opmodes, or
to demonstrate how a particular sensor or concept can be used directly on the
Pushbot chassis.
Concept: This is a sample OpMode that illustrates performing a specific function or concept.
These may be complex, but their operation should be explained clearly in the comments,
or the comments should reference an external doc, guide or tutorial.
Each OpMode should try to only demonstrate a single concept so they are easy to
locate based on their name.
Library: This is a class, or set of classes used to implement some strategy.
These will typically NOT implement a full opmode. Instead they will be included
by an OpMode to provide some stand-alone capability.
After the prefix, other conventions will apply:
* Sensor class names should constructed as: Sensor - Company - Type
* Hardware class names should be constructed as: Hardware - Robot type
* Pushbot class names should be constructed as: Pushbot - Mode - Action - OpModetype
* Concept class names should be constructed as: Concept - Topic - OpModetype
* Library class names should be constructed as: Library - Topic - OpModetype
### Sample OpMode Content/Style
Code is formatted as per the Google Style Guide:
https://google.github.io/styleguide/javaguide.html
With “Sensor” and “Hardware” samples, the code should demonstrate the essential function,
and not be embellished with too much additional “clever” code. If a sensor has special
addressing needs, or has a variety of modes or outputs, these should be demonstrated as
simply as possible.
Special programming methods, or robot control techniques should be reserved for “Concept” Samples,
and where possible, Samples should strive to only demonstrate a single concept,
eg: State machine coding, or a User Menu system, and not combine them into a single “all inclusive”
sample. This will prevent an “all inclusive” Sample being deleted just because one part of it
becomes obsolete.
### Device Configuration Names
The following device names are used in the external samples
** Motors:
left_drive
right_drive
left_arm
** Servos:
left_hand
right_hand
arm
claw
** Sensors:
sensor_color
sensor_ir
sensor_light
sensor_ods
sensor_range
sensor_touch
sensor_color_distance
sensor_digital
digin
digout
** Localization:
compass
gyro
imu
navx
### Device Object Names
Device Object names should use the same words as the device’s configuration name, but they
should be re-structured to be a suitable Java variable name. This should keep the same word order,
but adopt the style of beginning with a lower case letter, and then each subsequent word
starting with an upper case letter.
Eg: from the examples above: tool, leftMotor, rightClawServo, rearLightSensor.
Note: Sometimes it’s helpful to put the device type first, followed by the variant.
eg: motorLeft and motorRight, but this should only be done if the same word order
is used on the device configuration name.
### OpMode code Comments
Sample comments should read like normal code comments, that is, as an explanation of what the
sample code is doing. They should NOT be directives to the user,
like: “insert your joystick code here” as these comments typically aren’t
detailed enough to be useful. They also often get left in the code and become garbage.
Instead, an example of the joystick code should be shown with a comment describing what it is doing.
================================================
FILE: FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/FtcOpModeRegister.java
================================================
/* Copyright (c) 2014, 2015 Qualcomm Technologies Inc
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted (subject to the limitations in the disclaimer below) provided that
the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
Neither the name of Qualcomm Technologies Inc nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
package org.firstinspires.ftc.robotcontroller.internal;
import com.qualcomm.robotcore.eventloop.opmode.OpModeManager;
import com.qualcomm.robotcore.eventloop.opmode.OpModeRegister;
import org.firstinspires.ftc.robotcontroller.external.samples.ConceptNullOp;
/**
* {@link FtcOpModeRegister} is responsible for registering opmodes for use in an FTC game.
* @see #register(OpModeManager)
*/
public class FtcOpModeRegister implements OpModeRegister {
/**
* {@link #register(OpModeManager)} is called by the SDK game in order to register
* OpMode classes or instances that will participate in an FTC game.
*
* There are two mechanisms by which an OpMode may be registered.
*
* 1) The preferred method is by means of class annotations in the OpMode itself.
* See, for example the class annotations in {@link ConceptNullOp}.
*
* 2) The other, retired, method is to modify this {@link #register(OpModeManager)}
* method to include explicit calls to OpModeManager.register().
* This method of modifying this file directly is discouraged, as it
* makes updates to the SDK harder to integrate into your code.
*
* @param manager the object which contains methods for carrying out OpMode registrations
*
* @see com.qualcomm.robotcore.eventloop.opmode.TeleOp
* @see com.qualcomm.robotcore.eventloop.opmode.Autonomous
*/
public void register(OpModeManager manager) {
/**
* Any manual OpMode class registrations should go here.
*/
}
}
================================================
FILE: FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/FtcRobotControllerActivity.java
================================================
/* Copyright (c) 2014, 2015 Qualcomm Technologies Inc
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted (subject to the limitations in the disclaimer below) provided that
the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
Neither the name of Qualcomm Technologies Inc nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
package org.firstinspires.ftc.robotcontroller.internal;
import android.app.ActionBar;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.IBinder;
import android.preference.PreferenceManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.webkit.WebView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.PopupMenu;
import android.widget.TextView;
import com.google.blocks.ftcrobotcontroller.ProgrammingWebHandlers;
import com.google.blocks.ftcrobotcontroller.runtime.BlocksOpMode;
import com.qualcomm.ftccommon.ClassManagerFactory;
import com.qualcomm.ftccommon.FtcAboutActivity;
import com.qualcomm.ftccommon.FtcEventLoop;
import com.qualcomm.ftccommon.FtcEventLoopIdle;
import com.qualcomm.ftccommon.FtcRobotControllerService;
import com.qualcomm.ftccommon.FtcRobotControllerService.FtcRobotControllerBinder;
import com.qualcomm.ftccommon.FtcRobotControllerSettingsActivity;
import com.qualcomm.ftccommon.LaunchActivityConstantsList;
import com.qualcomm.ftccommon.LaunchActivityConstantsList.RequestCode;
import com.qualcomm.ftccommon.Restarter;
import com.qualcomm.ftccommon.UpdateUI;
import com.qualcomm.ftccommon.configuration.EditParameters;
import com.qualcomm.ftccommon.configuration.FtcLoadFileActivity;
import com.qualcomm.ftccommon.configuration.RobotConfigFile;
import com.qualcomm.ftccommon.configuration.RobotConfigFileManager;
import com.qualcomm.ftcrobotcontroller.BuildConfig;
import com.qualcomm.ftcrobotcontroller.R;
import com.qualcomm.hardware.HardwareFactory;
import com.qualcomm.robotcore.eventloop.EventLoopManager;
import com.qualcomm.robotcore.eventloop.opmode.FtcRobotControllerServiceState;
import com.qualcomm.robotcore.eventloop.opmode.OpModeRegister;
import com.qualcomm.robotcore.hardware.configuration.LynxConstants;
import com.qualcomm.robotcore.hardware.configuration.Utility;
import com.qualcomm.robotcore.robot.Robot;
import com.qualcomm.robotcore.robot.RobotState;
import com.qualcomm.robotcore.util.Device;
import com.qualcomm.robotcore.util.Dimmer;
import com.qualcomm.robotcore.util.ImmersiveMode;
import com.qualcomm.robotcore.util.RobotLog;
import com.qualcomm.robotcore.util.WebServer;
import com.qualcomm.robotcore.wifi.NetworkConnection;
import com.qualcomm.robotcore.wifi.NetworkConnectionFactory;
import com.qualcomm.robotcore.wifi.NetworkType;
import org.firstinspires.ftc.ftccommon.external.SoundPlayingRobotMonitor;
import org.firstinspires.ftc.ftccommon.internal.FtcRobotControllerWatchdogService;
import org.firstinspires.ftc.ftccommon.internal.ProgramAndManageActivity;
import org.firstinspires.ftc.onbotjava.OnBotJavaHelperImpl;
import org.firstinspires.ftc.onbotjava.OnBotJavaProgrammingMode;
import org.firstinspires.ftc.robotcore.external.navigation.MotionDetection;
import org.firstinspires.ftc.robotcore.internal.hardware.android.AndroidBoard;
import org.firstinspires.ftc.robotcore.internal.network.DeviceNameManagerFactory;
import org.firstinspires.ftc.robotcore.internal.network.PreferenceRemoterRC;
import org.firstinspires.ftc.robotcore.internal.network.StartResult;
import org.firstinspires.ftc.robotcore.internal.network.WifiDirectChannelChanger;
import org.firstinspires.ftc.robotcore.internal.network.WifiMuteEvent;
import org.firstinspires.ftc.robotcore.internal.network.WifiMuteStateMachine;
import org.firstinspires.ftc.robotcore.internal.opmode.ClassManager;
import org.firstinspires.ftc.robotcore.internal.system.AppUtil;
import org.firstinspires.ftc.robotcore.internal.system.Assert;
import org.firstinspires.ftc.robotcore.internal.system.PreferencesHelper;
import org.firstinspires.ftc.robotcore.internal.system.ServiceController;
import org.firstinspires.ftc.robotcore.internal.ui.ThemedActivity;
import org.firstinspires.ftc.robotcore.internal.ui.UILocation;
import org.firstinspires.ftc.robotcore.internal.webserver.RobotControllerWebInfo;
import org.firstinspires.ftc.robotserver.internal.programmingmode.ProgrammingModeManager;
import org.firstinspires.inspection.RcInspectionActivity;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
@SuppressWarnings("WeakerAccess")
public class FtcRobotControllerActivity extends Activity
{
public static final String TAG = "RCActivity";
public String getTag() { return TAG; }
private static final int REQUEST_CONFIG_WIFI_CHANNEL = 1;
private static final int NUM_GAMEPADS = 2;
protected WifiManager.WifiLock wifiLock;
protected RobotConfigFileManager cfgFileMgr;
protected ProgrammingModeManager programmingModeManager;
protected UpdateUI.Callback callback;
protected Context context;
protected Utility utility;
protected StartResult prefRemoterStartResult = new StartResult();
protected StartResult deviceNameStartResult = new StartResult();
protected PreferencesHelper preferencesHelper;
protected final SharedPreferencesListener sharedPreferencesListener = new SharedPreferencesListener();
protected ImageButton buttonMenu;
protected TextView textDeviceName;
protected TextView textNetworkConnectionStatus;
protected TextView textRobotStatus;
protected TextView[] textGamepad = new TextView[NUM_GAMEPADS];
protected TextView textOpMode;
protected TextView textErrorMessage;
protected ImmersiveMode immersion;
protected UpdateUI updateUI;
protected Dimmer dimmer;
protected LinearLayout entireScreenLayout;
protected FtcRobotControllerService controllerService;
protected NetworkType networkType;
protected FtcEventLoop eventLoop;
protected Queue receivedUsbAttachmentNotifications;
protected WifiMuteStateMachine wifiMuteStateMachine;
protected MotionDetection motionDetection;
private static boolean permissionsValidated = false;
private WifiDirectChannelChanger wifiDirectChannelChanger;
protected class RobotRestarter implements Restarter {
public void requestRestart() {
requestRobotRestart();
}
}
protected boolean serviceShouldUnbind = false;
protected ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
FtcRobotControllerBinder binder = (FtcRobotControllerBinder) service;
onServiceBind(binder.getService());
}
@Override
public void onServiceDisconnected(ComponentName name) {
RobotLog.vv(FtcRobotControllerService.TAG, "%s.controllerService=null", TAG);
controllerService = null;
}
};
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) {
UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
RobotLog.vv(TAG, "ACTION_USB_DEVICE_ATTACHED: %s", usbDevice.getDeviceName());
if (usbDevice != null) { // paranoia
// We might get attachment notifications before the event loop is set up, so
// we hold on to them and pass them along only when we're good and ready.
if (receivedUsbAttachmentNotifications != null) { // *total* paranoia
receivedUsbAttachmentNotifications.add(usbDevice);
passReceivedUsbAttachmentsToEventLoop();
}
}
}
}
protected void passReceivedUsbAttachmentsToEventLoop() {
if (this.eventLoop != null) {
for (;;) {
UsbDevice usbDevice = receivedUsbAttachmentNotifications.poll();
if (usbDevice == null)
break;
this.eventLoop.onUsbDeviceAttached(usbDevice);
}
}
else {
// Paranoia: we don't want the pending list to grow without bound when we don't
// (yet) have an event loop
while (receivedUsbAttachmentNotifications.size() > 100) {
receivedUsbAttachmentNotifications.poll();
}
}
}
/**
* There are cases where a permission may be revoked and the system restart will restart the
* FtcRobotControllerActivity, instead of the launch activity. Detect when that happens, and throw
* the device back to the permission validator activity.
*/
protected boolean enforcePermissionValidator() {
if (!permissionsValidated) {
RobotLog.vv(TAG, "Redirecting to permission validator");
Intent permissionValidatorIntent = new Intent(AppUtil.getDefContext(), PermissionValidatorWrapper.class);
startActivity(permissionValidatorIntent);
finish();
return true;
} else {
RobotLog.vv(TAG, "Permissions validated already");
return false;
}
}
public static void setPermissionsValidated() {
permissionsValidated = true;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (enforcePermissionValidator()) {
return;
}
RobotLog.onApplicationStart(); // robustify against onCreate() following onDestroy() but using the same app instance, which apparently does happen
RobotLog.vv(TAG, "onCreate()");
ThemedActivity.appAppThemeToActivity(getTag(), this); // do this way instead of inherit to help AppInventor
// Oddly, sometimes after a crash & restart the root activity will be something unexpected, like from the before crash? We don't yet understand
RobotLog.vv(TAG, "rootActivity is of class %s", AppUtil.getInstance().getRootActivity().getClass().getSimpleName());
RobotLog.vv(TAG, "launchActivity is of class %s", FtcRobotControllerWatchdogService.launchActivity());
Assert.assertTrue(FtcRobotControllerWatchdogService.isLaunchActivity(AppUtil.getInstance().getRootActivity()));
Assert.assertTrue(AppUtil.getInstance().isRobotController());
// Quick check: should we pretend we're not here, and so allow the Lynx to operate as
// a stand-alone USB-connected module?
if (LynxConstants.isRevControlHub()) {
// Double-sure check that we can talk to the DB over the serial TTY
AndroidBoard.getInstance().getAndroidBoardIsPresentPin().setState(true);
}
context = this;
utility = new Utility(this);
DeviceNameManagerFactory.getInstance().start(deviceNameStartResult);
PreferenceRemoterRC.getInstance().start(prefRemoterStartResult);
receivedUsbAttachmentNotifications = new ConcurrentLinkedQueue();
eventLoop = null;
setContentView(R.layout.activity_ftc_controller);
preferencesHelper = new PreferencesHelper(TAG, context);
preferencesHelper.writeBooleanPrefIfDifferent(context.getString(R.string.pref_rc_connected), true);
preferencesHelper.getSharedPreferences().registerOnSharedPreferenceChangeListener(sharedPreferencesListener);
entireScreenLayout = (LinearLayout) findViewById(R.id.entire_screen);
buttonMenu = (ImageButton) findViewById(R.id.menu_buttons);
buttonMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PopupMenu popupMenu = new PopupMenu(FtcRobotControllerActivity.this, v);
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
return onOptionsItemSelected(item); // Delegate to the handler for the hardware menu button
}
});
popupMenu.inflate(R.menu.ftc_robot_controller);
popupMenu.show();
}
});
updateMonitorLayout(getResources().getConfiguration());
BlocksOpMode.setActivityAndWebView(this, (WebView) findViewById(R.id.webViewBlocksRuntime));
/*
* Paranoia as the ClassManagerFactory requires EXTERNAL_STORAGE permissions
* and we've seen on the DS where the finish() call above does not short-circuit
* the onCreate() call for the activity and then we crash here because we don't
* have permissions. So...
*/
if (permissionsValidated) {
ClassManager.getInstance().setOnBotJavaClassHelper(new OnBotJavaHelperImpl());
ClassManagerFactory.registerFilters();
ClassManagerFactory.processAllClasses();
}
cfgFileMgr = new RobotConfigFileManager(this);
// Clean up 'dirty' status after a possible crash
RobotConfigFile configFile = cfgFileMgr.getActiveConfig();
if (configFile.isDirty()) {
configFile.markClean();
cfgFileMgr.setActiveConfig(false, configFile);
}
textDeviceName = (TextView) findViewById(R.id.textDeviceName);
textNetworkConnectionStatus = (TextView) findViewById(R.id.textNetworkConnectionStatus);
textRobotStatus = (TextView) findViewById(R.id.textRobotStatus);
textOpMode = (TextView) findViewById(R.id.textOpMode);
textErrorMessage = (TextView) findViewById(R.id.textErrorMessage);
textGamepad[0] = (TextView) findViewById(R.id.textGamepad1);
textGamepad[1] = (TextView) findViewById(R.id.textGamepad2);
immersion = new ImmersiveMode(getWindow().getDecorView());
dimmer = new Dimmer(this);
dimmer.longBright();
programmingModeManager = new ProgrammingModeManager();
programmingModeManager.register(new ProgrammingWebHandlers());
programmingModeManager.register(new OnBotJavaProgrammingMode());
updateUI = createUpdateUI();
callback = createUICallback(updateUI);
PreferenceManager.setDefaultValues(this, R.xml.app_settings, false);
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "");
hittingMenuButtonBrightensScreen();
wifiLock.acquire();
callback.networkConnectionUpdate(NetworkConnection.NetworkEvent.DISCONNECTED);
readNetworkType();
ServiceController.startService(FtcRobotControllerWatchdogService.class);
bindToService();
logPackageVersions();
logDeviceSerialNumber();
AndroidBoard.getInstance().logAndroidBoardInfo();
RobotLog.logDeviceInfo();
if (preferencesHelper.readBoolean(getString(R.string.pref_wifi_automute), false)) {
initWifiMute(true);
}
FtcAboutActivity.setBuildTimeFromBuildConfig(BuildConfig.BUILD_TIME);
}
protected UpdateUI createUpdateUI() {
Restarter restarter = new RobotRestarter();
UpdateUI result = new UpdateUI(this, dimmer);
result.setRestarter(restarter);
result.setTextViews(textNetworkConnectionStatus, textRobotStatus, textGamepad, textOpMode, textErrorMessage, textDeviceName);
return result;
}
protected UpdateUI.Callback createUICallback(UpdateUI updateUI) {
UpdateUI.Callback result = updateUI.new Callback();
result.setStateMonitor(new SoundPlayingRobotMonitor());
return result;
}
@Override
protected void onStart() {
super.onStart();
RobotLog.vv(TAG, "onStart()");
// If we're start()ing after a stop(), then shut the old robot down so
// we can refresh it with new state (e.g., with new hw configurations)
shutdownRobot();
updateUIAndRequestRobotSetup();
cfgFileMgr.getActiveConfigAndUpdateUI();
// check to see if there is a preferred Wi-Fi to use.
checkPreferredChannel();
entireScreenLayout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
dimmer.handleDimTimer();
return false;
}
});
}
@Override
protected void onResume() {
super.onResume();
RobotLog.vv(TAG, "onResume()");
}
@Override
protected void onPause() {
super.onPause();
RobotLog.vv(TAG, "onPause()");
}
@Override
protected void onStop() {
// Note: this gets called even when the configuration editor is launched. That is, it gets
// called surprisingly often. So, we don't actually do much here.
super.onStop();
RobotLog.vv(TAG, "onStop()");
}
@Override
protected void onDestroy() {
super.onDestroy();
RobotLog.vv(TAG, "onDestroy()");
shutdownRobot(); // Ensure the robot is put away to bed
if (callback != null) callback.close();
PreferenceRemoterRC.getInstance().stop(prefRemoterStartResult);
DeviceNameManagerFactory.getInstance().stop(deviceNameStartResult);
unbindFromService();
// If the app manually (?) is stopped, then we don't need the auto-starting function (?)
ServiceController.stopService(FtcRobotControllerWatchdogService.class);
if (wifiLock != null) wifiLock.release();
if (preferencesHelper != null) preferencesHelper.getSharedPreferences().unregisterOnSharedPreferenceChangeListener(sharedPreferencesListener);
RobotLog.cancelWriteLogcatToDisk();
}
protected void bindToService() {
readNetworkType();
Intent intent = new Intent(this, FtcRobotControllerService.class);
intent.putExtra(NetworkConnectionFactory.NETWORK_CONNECTION_TYPE, networkType);
serviceShouldUnbind = bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
protected void unbindFromService() {
if (serviceShouldUnbind) {
unbindService(connection);
serviceShouldUnbind = false;
}
}
protected void logPackageVersions() {
RobotLog.logBuildConfig(com.qualcomm.ftcrobotcontroller.BuildConfig.class);
RobotLog.logBuildConfig(com.qualcomm.robotcore.BuildConfig.class);
RobotLog.logBuildConfig(com.qualcomm.hardware.BuildConfig.class);
RobotLog.logBuildConfig(com.qualcomm.ftccommon.BuildConfig.class);
RobotLog.logBuildConfig(com.google.blocks.BuildConfig.class);
RobotLog.logBuildConfig(org.firstinspires.inspection.BuildConfig.class);
}
protected void logDeviceSerialNumber() {
RobotLog.ii(TAG, "Android device serial number: " + Device.getSerialNumberOrUnknown());
}
protected void readNetworkType() {
// The code here used to defer to the value found in a configuration file
// to configure the network type. If the file was absent, then it initialized
// it with a default.
//
// However, bugs have been reported with that approach (empty config files, specifically).
// 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.
//
// 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_pairing_kind), networkType.toString());
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
immersion.hideSystemUI();
getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.ftc_robot_controller, menu);
return true;
}
private boolean isRobotRunning() {
if (controllerService == null) {
return false;
}
Robot robot = controllerService.getRobot();
if ((robot == null) || (robot.eventLoopManager == null)) {
return false;
}
RobotState robotState = robot.eventLoopManager.state;
if (robotState != RobotState.RUNNING) {
return false;
} else {
return true;
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_program_and_manage) {
if (isRobotRunning()) {
Intent programmingModeIntent = new Intent(AppUtil.getDefContext(), ProgramAndManageActivity.class);
RobotControllerWebInfo webInfo = programmingModeManager.getWebServer().getConnectionInformation();
programmingModeIntent.putExtra(LaunchActivityConstantsList.RC_WEB_INFO, webInfo.toJson());
startActivity(programmingModeIntent);
} else {
AppUtil.getInstance().showToast(UILocation.ONLY_LOCAL, context.getString(R.string.toastWifiUpBeforeProgrammingMode));
}
} else if (id == R.id.action_inspection_mode) {
Intent inspectionModeIntent = new Intent(AppUtil.getDefContext(), RcInspectionActivity.class);
startActivity(inspectionModeIntent);
return true;
} else if (id == R.id.action_restart_robot) {
dimmer.handleDimTimer();
AppUtil.getInstance().showToast(UILocation.BOTH, context.getString(R.string.toastRestartingRobot));
requestRobotRestart();
return true;
}
else if (id == R.id.action_configure_robot) {
EditParameters parameters = new EditParameters();
Intent intentConfigure = new Intent(AppUtil.getDefContext(), FtcLoadFileActivity.class);
parameters.putIntent(intentConfigure);
startActivityForResult(intentConfigure, RequestCode.CONFIGURE_ROBOT_CONTROLLER.ordinal());
}
else if (id == R.id.action_settings) {
// historical: this once erroneously used FTC_CONFIGURE_REQUEST_CODE_ROBOT_CONTROLLER
Intent settingsIntent = new Intent(AppUtil.getDefContext(), FtcRobotControllerSettingsActivity.class);
startActivityForResult(settingsIntent, RequestCode.SETTINGS_ROBOT_CONTROLLER.ordinal());
return true;
}
else if (id == R.id.action_about) {
Intent intent = new Intent(AppUtil.getDefContext(), FtcAboutActivity.class);
startActivity(intent);
return true;
}
else if (id == R.id.action_exit_app) {
//Clear backstack and everything to prevent edge case where VM might be
//restarted (after it was exited) if more than one activity was on the
//backstack for some reason.
finishAffinity();
//For lollipop and up, we can clear ourselves from the recents list too
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List tasks = manager.getAppTasks();
for (ActivityManager.AppTask task : tasks) {
task.finishAndRemoveTask();
}
}
//Finally, nuke the VM from orbit
AppUtil.getInstance().exitApplication();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// don't destroy assets on screen rotation
updateMonitorLayout(newConfig);
}
/**
* Updates the orientation of monitorContainer (which contains cameraMonitorView and
* tfodMonitorView) based on the given configuration. Makes the children split the space.
*/
private void updateMonitorLayout(Configuration configuration) {
LinearLayout monitorContainer = (LinearLayout) findViewById(R.id.monitorContainer);
if (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
// When the phone is landscape, lay out the monitor views horizontally.
monitorContainer.setOrientation(LinearLayout.HORIZONTAL);
for (int i = 0; i < monitorContainer.getChildCount(); i++) {
View view = monitorContainer.getChildAt(i);
view.setLayoutParams(new LayoutParams(0, LayoutParams.MATCH_PARENT, 1 /* weight */));
}
} else {
// When the phone is portrait, lay out the monitor views vertically.
monitorContainer.setOrientation(LinearLayout.VERTICAL);
for (int i = 0; i < monitorContainer.getChildCount(); i++) {
View view = monitorContainer.getChildAt(i);
view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 0, 1 /* weight */));
}
}
monitorContainer.requestLayout();
}
@Override
protected void onActivityResult(int request, int result, Intent intent) {
if (request == REQUEST_CONFIG_WIFI_CHANNEL) {
if (result == RESULT_OK) {
AppUtil.getInstance().showToast(UILocation.BOTH, context.getString(R.string.toastWifiConfigurationComplete));
}
}
// was some historical confusion about launch codes here, so we err safely
if (request == RequestCode.CONFIGURE_ROBOT_CONTROLLER.ordinal() || request == RequestCode.SETTINGS_ROBOT_CONTROLLER.ordinal()) {
// We always do a refresh, whether it was a cancel or an OK, for robustness
cfgFileMgr.getActiveConfigAndUpdateUI();
}
}
public void onServiceBind(final FtcRobotControllerService service) {
RobotLog.vv(FtcRobotControllerService.TAG, "%s.controllerService=bound", TAG);
controllerService = service;
updateUI.setControllerService(controllerService);
updateUIAndRequestRobotSetup();
programmingModeManager.setState(new FtcRobotControllerServiceState() {
@NonNull
@Override
public WebServer getWebServer() {
return service.getWebServer();
}
@Override
public EventLoopManager getEventLoopManager() {
return service.getRobot().eventLoopManager;
}
});
}
private void updateUIAndRequestRobotSetup() {
if (controllerService != null) {
callback.networkConnectionUpdate(controllerService.getNetworkConnectionStatus());
callback.updateRobotStatus(controllerService.getRobotStatus());
// Only show this first-time toast on headless systems: what we have now on non-headless suffices
requestRobotSetup(LynxConstants.isRevControlHub()
? new Runnable() {
@Override public void run() {
showRestartRobotCompleteToast(R.string.toastRobotSetupComplete);
}
}
: null);
}
}
private void requestRobotSetup(@Nullable Runnable runOnComplete) {
if (controllerService == null) return;
RobotConfigFile file = cfgFileMgr.getActiveConfigAndUpdateUI();
HardwareFactory hardwareFactory = new HardwareFactory(context);
try {
hardwareFactory.setXmlPullParser(file.getXml());
} catch (Resources.NotFoundException e) {
file = RobotConfigFile.noConfig(cfgFileMgr);
hardwareFactory.setXmlPullParser(file.getXml());
cfgFileMgr.setActiveConfigAndUpdateUI(false, file);
}
OpModeRegister userOpModeRegister = createOpModeRegister();
eventLoop = new FtcEventLoop(hardwareFactory, userOpModeRegister, callback, this);
FtcEventLoopIdle idleLoop = new FtcEventLoopIdle(hardwareFactory, userOpModeRegister, callback, this);
controllerService.setCallback(callback);
controllerService.setupRobot(eventLoop, idleLoop, runOnComplete);
passReceivedUsbAttachmentsToEventLoop();
AndroidBoard.showErrorIfUnknownControlHub();
}
protected OpModeRegister createOpModeRegister() {
return new FtcOpModeRegister();
}
private void shutdownRobot() {
if (controllerService != null) controllerService.shutdownRobot();
}
private void requestRobotRestart() {
AppUtil.getInstance().showToast(UILocation.BOTH, AppUtil.getDefContext().getString(R.string.toastRestartingRobot));
//
RobotLog.clearGlobalErrorMsg();
RobotLog.clearGlobalWarningMsg();
shutdownRobot();
requestRobotSetup(new Runnable() {
@Override public void run() {
showRestartRobotCompleteToast(R.string.toastRestartRobotComplete);
}
});
}
private void showRestartRobotCompleteToast(@StringRes int resid) {
AppUtil.getInstance().showToast(UILocation.BOTH, AppUtil.getDefContext().getString(resid));
}
private void checkPreferredChannel() {
// For P2P network, check to see what preferred channel is.
if (networkType == NetworkType.WIFIDIRECT) {
int prefChannel = preferencesHelper.readInt(getString(com.qualcomm.ftccommon.R.string.pref_wifip2p_channel), -1);
if (prefChannel == -1) {
prefChannel = 0;
RobotLog.vv(TAG, "pref_wifip2p_channel: No preferred channel defined. Will use a default value of %d", prefChannel);
} else {
RobotLog.vv(TAG, "pref_wifip2p_channel: Found existing preferred channel (%d).", prefChannel);
}
// attempt to set the preferred channel.
RobotLog.vv(TAG, "pref_wifip2p_channel: attempting to set preferred channel...");
wifiDirectChannelChanger = new WifiDirectChannelChanger();
wifiDirectChannelChanger.changeToChannel(prefChannel);
}
}
protected void hittingMenuButtonBrightensScreen() {
ActionBar actionBar = getActionBar();
if (actionBar != null) {
actionBar.addOnMenuVisibilityListener(new ActionBar.OnMenuVisibilityListener() {
@Override
public void onMenuVisibilityChanged(boolean isVisible) {
if (isVisible) {
dimmer.handleDimTimer();
}
}
});
}
}
protected class SharedPreferencesListener implements SharedPreferences.OnSharedPreferenceChangeListener {
@Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(context.getString(R.string.pref_app_theme))) {
ThemedActivity.restartForAppThemeChange(getTag(), getString(R.string.appThemeChangeRestartNotifyRC));
} else if (key.equals(context.getString(R.string.pref_wifi_automute))) {
if (preferencesHelper.readBoolean(context.getString(R.string.pref_wifi_automute), false)) {
initWifiMute(true);
} else {
initWifiMute(false);
}
}
}
}
protected void initWifiMute(boolean enable) {
if (enable) {
wifiMuteStateMachine = new WifiMuteStateMachine();
wifiMuteStateMachine.initialize();
wifiMuteStateMachine.start();
motionDetection = new MotionDetection(2.0, 10);
motionDetection.startListening();
motionDetection.registerListener(new MotionDetection.MotionDetectionListener() {
@Override
public void onMotionDetected(double vector)
{
wifiMuteStateMachine.consumeEvent(WifiMuteEvent.USER_ACTIVITY);
}
});
} else {
wifiMuteStateMachine.stop();
wifiMuteStateMachine = null;
motionDetection.stopListening();
motionDetection.purgeListeners();
motionDetection = null;
}
}
@Override
public void onUserInteraction() {
if (wifiMuteStateMachine != null) {
wifiMuteStateMachine.consumeEvent(WifiMuteEvent.USER_ACTIVITY);
}
}
}
================================================
FILE: FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/internal/PermissionValidatorWrapper.java
================================================
/*
* Copyright (c) 2018 Craig MacFarlane
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* (subject to the limitations in the disclaimer below) provided that the following conditions are
* met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions
* and the following disclaimer in the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Craig MacFarlane nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. THIS
* SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.firstinspires.ftc.robotcontroller.internal;
import android.Manifest;
import android.os.Bundle;
import com.qualcomm.ftcrobotcontroller.R;
import org.firstinspires.ftc.robotcore.internal.system.Misc;
import org.firstinspires.ftc.robotcore.internal.system.PermissionValidatorActivity;
import java.util.ArrayList;
import java.util.List;
public class PermissionValidatorWrapper extends PermissionValidatorActivity {
private final String TAG = "PermissionValidatorWrapper";
/*
* The list of dangerous permissions the robot controller needs.
*/
protected List robotControllerPermissions = new ArrayList() {{
add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
add(Manifest.permission.READ_EXTERNAL_STORAGE);
add(Manifest.permission.CAMERA);
add(Manifest.permission.ACCESS_COARSE_LOCATION);
add(Manifest.permission.ACCESS_FINE_LOCATION);
add(Manifest.permission.READ_PHONE_STATE);
}};
private final static Class startApplication = FtcRobotControllerActivity.class;
public String mapPermissionToExplanation(final String permission) {
if (permission.equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
return Misc.formatForUser(R.string.permRcWriteExternalStorageExplain);
} else if (permission.equals(Manifest.permission.READ_EXTERNAL_STORAGE)) {
return Misc.formatForUser(R.string.permRcReadExternalStorageExplain);
} else if (permission.equals(Manifest.permission.CAMERA)) {
return Misc.formatForUser(R.string.permRcCameraExplain);
} else if (permission.equals(Manifest.permission.ACCESS_COARSE_LOCATION)) {
return Misc.formatForUser(R.string.permAccessLocationExplain);
} else if (permission.equals(Manifest.permission.ACCESS_FINE_LOCATION)) {
return Misc.formatForUser(R.string.permAccessLocationExplain);
} else if (permission.equals(Manifest.permission.READ_PHONE_STATE)) {
return Misc.formatForUser(R.string.permReadPhoneState);
}
return Misc.formatForUser(R.string.permGenericExplain);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
permissions = robotControllerPermissions;
}
protected Class onStartApplication()
{
FtcRobotControllerActivity.setPermissionsValidated();
return startApplication;
}
}
================================================
FILE: FtcRobotController/src/main/res/layout/activity_ftc_controller.xml
================================================
================================================
FILE: FtcRobotController/src/main/res/menu/ftc_robot_controller.xml
================================================
================================================
FILE: FtcRobotController/src/main/res/values/dimens.xml
================================================
16dp
5dp
================================================
FILE: FtcRobotController/src/main/res/values/strings.xml
================================================
FTC Robot Controller
Self Inspect
Program & Manage
Blocks
Settings
Restart Robot
Configure Robot
About
Exit
Configuration Complete
Restarting Robot
The Robot Controller must be fully up and running before entering Program and Manage Mode.
- @style/AppThemeRedRC
- @style/AppThemeGreenRC
- @style/AppThemeBlueRC
- @style/AppThemePurpleRC
- @style/AppThemeOrangeRC
- @style/AppThemeTealRC
@string/packageNameRobotController
================================================
FILE: FtcRobotController/src/main/res/values/styles.xml
================================================
================================================
FILE: FtcRobotController/src/main/res/values-sw600dp/dimens.xml
================================================
================================================
FILE: FtcRobotController/src/main/res/values-sw720dp-land/dimens.xml
================================================
128dp
================================================
FILE: FtcRobotController/src/main/res/values-w820dp/dimens.xml
================================================
64dp
================================================
FILE: FtcRobotController/src/main/res/xml/app_settings.xml
================================================
================================================
FILE: FtcRobotController/src/main/res/xml/device_filter.xml
================================================
================================================
FILE: README.md
================================================
## NOTICE
This repository contains the public FTC SDK for the SKYSTONE (2019-2020) competition season. If you are looking for the current season's FTC SDK software, please visit the new and permanent home of the public FTC SDK:
[FtcRobotController repository](https://github.com/FIRST-Tech-Challenge/FtcRobotController)
## Welcome!
This GitHub repository contains the source code that is used to build an Android app to control a *FIRST* Tech Challenge competition robot. To use this SDK, download/clone the entire project to your local computer.
## Getting Started
If you are new to robotics or new to the *FIRST* Tech Challenge, then you should consider reviewing the [FTC Blocks Tutorial](https://github.com/FIRST-Tech-Challenge/SKYSTONE/wiki/Blocks-Tutorial) to get familiar with how to use the control system:
[FTC Blocks Online Tutorial](https://github.com/FIRST-Tech-Challenge/SKYSTONE/wiki/Blocks-Tutorial)
Even if you are an advanced Java programmer, it is helpful to start with the [FTC Blocks tutorial](https://github.com/FIRST-Tech-Challenge/SKYSTONE/wiki/Blocks-Tutorial), and then migrate to the [OnBot Java Tool](https://github.com/FIRST-Tech-Challenge/SKYSTONE/wiki/OnBot-Java-Tutorial) or to [Android Studio](https://github.com/FIRST-Tech-Challenge/SKYSTONE/wiki/Android-Studio-Tutorial) afterwards.
## Downloading the Project
If you are an Android Studio programmer, there are several ways to download this repo. Note that if you use the Blocks or OnBot Java Tool to program your robot, then you do not need to download this repository.
* If you are a git user, you can clone the most current version of the repository:
git clone https://github.com/FIRST-Tech-Challenge/SKYSTONE.git
* Or, if you prefer, you can use the "Download Zip" button available through the main repository page. Downloading the project as a .ZIP file will keep the size of the download manageable.
* You can also download the project folder (as a .zip or .tar.gz archive file) from the Downloads subsection of the [Releases](https://github.com/FIRST-Tech-Challenge/SKYSTONE/releases) page for this repository.
Once you have downloaded and uncompressed (if needed) your folder, you can use Android Studio to import the folder ("Import project (Eclipse ADT, Gradle, etc.)").
## Getting Help
### User Documentation and Tutorials
*FIRST* maintains online documentation with information and tutorials on how to use the *FIRST* Tech Challenge software and robot control system. You can access this documentation using the following link:
[SKYSTONE Online Documentation](https://github.com/FIRST-Tech-Challenge/SKYSTONE/wiki)
Note that the online documentation is an "evergreen" document that is constantly being updated and edited. It contains the most current information about the *FIRST* Tech Challenge software and control system.
### Javadoc Reference Material
The Javadoc reference documentation for the FTC SDK is now available online. Click on the following link to view the FTC SDK Javadoc documentation as a live website:
[FTC Javadoc Documentation](https://first-tech-challenge.github.io/SkyStone/)
Documentation for the FTC SDK is also included with this repository. There is a subfolder called "doc" which contains several subfolders:
* The folder "apk" contains the .apk files for the FTC Driver Station and FTC Robot Controller apps.
* The folder "javadoc" contains the JavaDoc user documentation for the FTC SDK.
### Online User Forum
For technical questions regarding the Control System or the FTC SDK, please visit the FTC Technology forum:
[FTC Technology Forum](https://ftcforum.usfirst.org/forumdisplay.php?156-FTC-Technology)
# Release Information
## Version 5.5 (20200824-090813)
Version 5.5 requires Android Studio 4.0 or later.
### New features
* Adds support for calling custom Java classes from Blocks OpModes (fixes [SkyStone issue #161](https://github.com/FIRST-Tech-Challenge/SkyStone/issues/161)).
* Classes must be in the org.firstinspires.ftc.teamcode package.
* Methods must be public static and have no more than 21 parameters.
* Parameters declared as OpMode, LinearOpMode, Telemetry, and HardwareMap are supported and the
argument is provided automatically, regardless of the order of the parameters. On the block,
the sockets for those parameters are automatically filled in.
* Parameters declared as char or java.lang.Character will accept any block that returns text
and will only use the first character in the text.
* Parameters declared as boolean or java.lang.Boolean will accept any block that returns boolean.
* Parameters declared as byte, java.lang.Byte, short, java.lang.Short, int, java.lang.Integer,
long, or java.lang.Long, will accept any block that returns a number and will round that
value to the nearest whole number.
* Parameters declared as float, java.lang.Float, double, java.lang.Double will accept any
block that returns a number.
* Adds telemetry API method for setting display format
* Classic
* Monospace
* HTML (certain tags only)
* Adds blocks support for switching cameras.
* Adds Blocks support for TensorFlow Object Detection with a custom model.
* Adds support for uploading a custom TensorFlow Object Detection model in the Manage page, which
is especially useful for Blocks and OnBotJava users.
* Shows new Control Hub blink codes when the WiFi band is switched using the Control Hub's button (only possible on Control Hub OS 1.1.2)
* Adds new warnings which can be disabled in the Advanced RC Settings
* Mismatched app versions warning
* Unnecessary 2.4 GHz WiFi usage warning
* REV Hub is running outdated firmware (older than version 1.8.2)
* Adds support for Sony PS4 gamepad, and reworks how gamepads work on the Driver Station
* Removes preference which sets gamepad type based on driver position. Replaced with menu which allows specifying type for gamepads with unknown VID and PID
* Attempts to auto-detect gamepad type based on USB VID and PID
* If gamepad VID and PID is not known, use type specified by user for that VID and PID
* If gamepad VID and PID is not known AND the user has not specified a type for that VID and PID, an educated guess is made about how to map the gamepad
* Driver Station will now attempt to automatically recover from a gamepad disconnecting, and re-assign it to the position it was assigned to when it dropped
* If only one gamepad is assigned and it drops: it can be recovered
* If two gamepads are assigned, and have **different** VID/PID signatures, and only one drops: it will be recovered
* If two gamepads are assigned, and have **different** VID/PID signatures, and BOTH drop: both will be recovered
* If two gamepads are assigned, and have **the same** VID/PID signatures, and only one drops: it will be recovered
* If two gamepads are assigned, and have **the same** VID/PID signatures, and BOTH drop: **neither** will be recovered, because of the ambiguity of the gamepads when they re-appear on the USB bus.
* There is currently one known edge case: if there are **two** gamepads with **the same** VID/PID signature plugged in, **but only one is assigned**, and they BOTH drop, it's a 50-50 chance of which one will be chosen for automatic recovery to the assigned position: it is determined by whichever one is re-enumerated first by the USB bus controller.
* Adds landscape user interface to Driver Station
* New feature: practice timer with audio cues
* New feature (Control Hub only): wireless network connection strength indicator (0-5 bars)
* New feature (Control Hub only): tapping on the ping/channel display will switch to an alternate display showing radio RX dBm and link speed (tap again to switch back)
* The layout will NOT autorotate. You can switch the layout from the Driver Station's settings menu.
### Breaking changes
* Removes support for Android versions 4.4 through 5.1 (KitKat and Lollipop). The minSdkVersion is now 23.
* Removes the deprecated `LinearOpMode` methods `waitOneFullHardwareCycle()` and `waitForNextHardwareCycle()`
### Enhancements
* Handles RS485 address of Control Hub automatically
* The Control Hub is automatically given a reserved address
* Existing configuration files will continue to work
* All addresses in the range of 1-10 are still available for Expansion Hubs
* The Control Hub light will now normally be solid green, without blinking to indicate the address
* The Control Hub will not be shown on the Expansion Hub Address Change settings page
* Improves REV Hub firmware updater
* The user can now choose between all available firmware update files
* Version 1.8.2 of the REV Hub firmware is bundled into the Robot Controller app.
* Text was added to clarify that Expansion Hubs can only be updated via USB.
* Firmware update speed was reduced to improve reliability
* Allows REV Hub firmware to be updated directly from the Manage webpage
* Improves log viewer on Robot Controller
* Horizontal scrolling support (no longer word wrapped)
* Supports pinch-to-zoom
* Uses a monospaced font
* Error messages are highlighted
* New color scheme
* Attempts to force-stop a runaway/stuck OpMode without restarting the entire app
* Not all types of runaway conditions are stoppable, but if the user code attempts to talk to hardware during the runaway, the system should be able to capture it.
* Makes various tweaks to the Self Inspect screen
* Renames "OS version" entry to "Android version"
* Renames "WiFi Direct Name" to "WiFi Name"
* Adds Control Hub OS version, when viewing the report of a Control Hub
* Hides the airplane mode entry, when viewing the report of a Control Hub
* Removes check for ZTE Speed Channel Changer
* Shows firmware version for **all** Expansion and Control Hubs
* Reworks network settings portion of Manage page
* All network settings are now applied with a single click
* The WiFi Direct channel of phone-based Robot Controllers can now be changed from the Manage page
* WiFi channels are filtered by band (2.4 vs 5 GHz) and whether they overlap with other channels
* The current WiFi channel is pre-selected on phone-based Robot Controllers, and Control Hubs running OS 1.1.2 or later.
* On Control Hubs running OS 1.1.2 or later, you can choose to have the system automatically select a channel on the 5 GHz band
* Improves OnBotJava
* New light and dark themes replace the old themes (chaos, github, chrome,...)
* the new default theme is `light` and will be used when you first update to this version
* OnBotJava now has a tabbed editor
* Read-only offline mode
* Improves function of "exit" menu item on Robot Controller and Driver Station
* Now guaranteed to be fully stopped and unloaded from memory
* Shows a warning message if a LinearOpMode exists prematurely due to failure to monitor for the start condition
* Improves error message shown when the Driver Station and Robot Controller are incompatible with each other
* Driver Station OpMode Control Panel now disabled while a Restart Robot is in progress
* Disables advanced settings related to WiFi direct when the Robot Controller is a Control Hub.
* Tint phone battery icons on Driver Station when low/critical.
* Uses names "Control Hub Portal" and "Control Hub" (when appropriate) in new configuration files
* Improve I2C read performance
* Very large improvement on Control Hub; up to ~2x faster with small (e.g. 6 byte) reads
* Not as apparent on Expansion Hubs connected to a phone
* Update/refresh build infrastructure
* Update to 'androidx' support library from 'com.android.support:appcompat', which is end-of-life
* Update targetSdkVersion and compileSdkVersion to 28
* Update Android Studio's Android plugin to latest
* Fix reported build timestamp in 'About' screen
* Add sample illustrating manual webcam use: ConceptWebcam
### Bug fixes
* Fixes [SkyStone issue #248](https://github.com/FIRST-Tech-Challenge/SkyStone/issues/248)
* Fixes [SkyStone issue #232](https://github.com/FIRST-Tech-Challenge/SkyStone/issues/232) and
modifies bulk caching semantics to allow for cache-preserving MANUAL/AUTO transitions.
* Improves performance when REV 2M distance sensor is unplugged
* Improves readability of Toast messages on certain devices
* Allows a Driver Station to connect to a Robot Controller after another has disconnected
* Improves generation of fake serial numbers for UVC cameras which do not provide a real serial number
* Previously some devices would assign such cameras a serial of `0:0` and fail to open and start streaming
* Fixes [ftc_app issue #638](https://github.com/ftctechnh/ftc_app/issues/638).
* Fixes a slew of bugs with the Vuforia camera monitor including:
* Fixes bug where preview could be displayed with a wonky aspect ratio
* Fixes bug where preview could be cut off in landscape
* Fixes bug where preview got totally messed up when rotating phone
* Fixes bug where crosshair could drift off target when using webcams
* Fixes issue in UVC driver on some devices ([ftc_app 681](https://github.com/ftctechnh/ftc_app/issues/681)) if streaming was started/stopped multiple times in a row
* Issue manifested as kernel panic on devices which do not have [this kernel patch](https://lore.kernel.org/patchwork/patch/352400/).
* On affected devices which **do** have the patch, the issue was manifest as simply a failure to start streaming.
* The Tech Team believes that the root cause of the issue is a bug in the Linux kernel XHCI driver. A workaround was implemented in the SDK UVC driver.
* Fixes bug in UVC driver where often half the frames from the camera would be dropped (e.g. only 15FPS delivered during a streaming session configured for 30FPS).
* Fixes issue where TensorFlow Object Detection would show results whose confidence was lower than
the minimum confidence parameter.
* Fixes a potential exploitation issue of [CVE-2019-11358](https://www.cvedetails.com/cve/CVE-2019-11358/) in OnBotJava
* Fixes changing the address of an Expansion Hub with additional Expansion Hubs connected to it
* Preserves the Control Hub's network connection when "Restart Robot" is selected
* Fixes issue where device scans would fail while the Robot was restarting
* Fix RenderScript usage
* Use androidx.renderscript variant: increased compatibility
* Use RenderScript in Java mode, not native: simplifies build
* Fixes webcam-frame-to-bitmap conversion problem: alpha channel wasn't being initialized, only R, G, & B
* Fixes possible arithmetic overflow in Deadline
* Fixes deadlock in Vuforia webcam support which could cause 5-second delays when stopping OpMode
## Version 5.4 (20200108-101156)
* Fixes [SkyStone issue #88](https://github.com/FIRST-Tech-Challenge/SkyStone/issues/88)
* Adds an inspection item that notes when a robot controller (Control Hub) is using the factory default password.
* Fixes [SkyStone issue #61](https://github.com/FIRST-Tech-Challenge/SkyStone/issues/61)
* Fixes [SkyStone issue #142](https://github.com/FIRST-Tech-Challenge/SkyStone/issues/142)
* Fixes [ftc_app issue #417](https://github.com/ftctechnh/ftc_app/issues/417) by adding more current and voltage monitoring capabilities for REV Hubs.
* Fixes [a crash sometimes caused by OnBotJava activity](https://ftcforum.firstinspires.org/forum/ftc-technology/76217-onbotjava-crashes-robot-controller)
* Improves OnBotJava autosave functionality [ftc_app #738](https://github.com/ftctechnh/ftc_app/issues/738)
* Fixes system responsiveness issue when an Expansion Hub is disconnected
* Fixes issue where IMU initialization could prevent Op Modes from stopping
* Fixes issue where AndroidTextToSpeech.speak() would fail if it was called too early
* Adds telemetry.speak() methods and blocks, which cause the Driver Station (if also updated) to speak text
* Adds and improves Expansion Hub-related warnings
* Improves Expansion Hub low battery warning
* Displays the warning immediately after the hub reports it
* Specifies whether the condition is current or occurred temporarily during an OpMode run
* Displays which hubs reported low battery
* Displays warning when hub loses and regains power during an OpMode run
* Fixes the hub's LED pattern after this condition
* Displays warning when Expansion Hub is not responding to commands
* Specifies whether the condition is current or occurred temporarily during an OpMode run
* Clarifies warning when Expansion Hub is not present at startup
* Specifies that this condition requires a Robot Restart before the hub can be used.
* The hub light will now accurately reflect this state
* Improves logging and reduces log spam during these conditions
* Syncs the Control Hub time and timezone to a connected web browser programming the robot, if a Driver Station is not available.
* Adds bulk read functionality for REV Hubs
* A bulk caching mode must be set at the Hub level with `LynxModule#setBulkCachingMode()`. This applies to all relevant SDK hardware classes that reference that Hub.
* The following following Hub bulk caching modes are available:
* `BulkCachingMode.OFF` (default): All hardware calls operate as usual. Bulk data can read through `LynxModule#getBulkData()` and processed manually.
* `BulkCachingMode.AUTO`: Applicable hardware calls are served from a bulk read cache that is cleared/refreshed automatically to ensure identical commands don't hit the same cache. The cache can also be cleared manually with `LynxModule#clearBulkCache()`, although this is not recommended.
* (advanced users) `BulkCachingMode.MANUAL`: Same as `BulkCachingMode.AUTO` except the cache is never cleared automatically. To avoid getting stale data, the cache must be manually cleared at the beginning of each loop body or as the user deems appropriate.
* Removes PIDF Annotation values added in Rev 5.3 (to AndyMark, goBILDA and TETRIX motor configurations).
* The new motor types will still be available but their Default control behavior will revert back to Rev 5.2
* Adds new `ConceptMotorBulkRead` sample Opmode to demonstrate and compare Motor Bulk-Read modes for reducing I/O latencies.
## Version 5.3 (20191004-112306)
* Fixes external USB/UVC webcam support
* Makes various bugfixes and improvements to Blocks page, including but not limited to:
* Many visual tweaks
* Browser zoom and window resize behave better
* Resizing the Java preview pane works better and more consistently across browsers
* The Java preview pane consistently gets scrollbars when needed
* The Java preview pane is hidden by default on phones
* Internet Explorer 11 should work
* Large dropdown lists display properly on lower res screens
* Disabled buttons are now visually identifiable as disabled
* A warning is shown if a user selects a TFOD sample, but their device is not compatible
* Warning messages in a Blocks op mode are now visible by default.
* Adds goBILDA 5201 and 5202 motors to Robot Configurator
* Adds PIDF Annotation values to AndyMark, goBILDA and TETRIX motor configurations.
This has the effect of causing the RUN_USING_ENCODERS and RUN_TO_POSITION modes to use
PIDF vs PID closed loop control on these motors. This should provide more responsive, yet stable, speed control.
PIDF adds Feedforward control to the basic PID control loop.
Feedforward is useful when controlling a motor's speed because it "anticipates" how much the control voltage
must change to achieve a new speed set-point, rather than requiring the integrated error to change sufficiently.
The PIDF values were chosen to provide responsive, yet stable, speed control on a lightly loaded motor.
The more heavily a motor is loaded (drag or friction), the more noticable the PIDF improvement will be.
* Fixes startup crash on Android 10
* Fixes [ftc_app issue #712](https://github.com/ftctechnh/ftc_app/issues/712) (thanks to FROGbots-4634)
* Fixes [ftc_app issue #542](https://github.com/ftctechnh/ftc_app/issues/542)
* Allows "A" and lowercase letters when naming device through RC and DS apps.
## Version 5.2 (20190905-083277)
* Fixes extra-wide margins on settings activities, and placement of the new configuration button
* Adds Skystone Vuforia image target data.
* Includes sample Skystone Vuforia Navigation op modes (Java).
* Includes sample Skystone Vuforia Navigation op modes (Blocks).
* Adds TensorFlow inference model (.tflite) for Skystone game elements.
* Includes sample Skystone TensorFlow op modes (Java).
* Includes sample Skystone TensorFlow op modes (Blocks).
* Removes older (season-specific) sample op modes.
* Includes 64-bit support (to comply with [Google Play requirements](https://android-developers.googleblog.com/2019/01/get-your-apps-ready-for-64-bit.html)).
* Protects against Stuck OpModes when a Restart Robot is requested. (Thanks to FROGbots-4634) ([ftc_app issue #709](https://github.com/ftctechnh/ftc_app/issues/709))
* Blocks related changes:
* Fixes bug with blocks generated code when hardware device name is a java or javascript reserved word.
* Shows generated java code for blocks, even when hardware items are missing from the active configuration.
* Displays warning icon when outdated Vuforia and TensorFlow blocks are used ([SkyStone issue #27](https://github.com/FIRST-Tech-Challenge/SkyStone/issues/27))
## Version 5.1 (20190820-222104)
* Defines default PIDF parameters for the following motors:
* REV Core Hex Motor
* REV 20:1 HD Hex Motor
* REV 40:1 HD Hex Motor
* Adds back button when running on a device without a system back button (such as a Control Hub)
* Allows a REV Control Hub to update the firmware on a REV Expansion Hub via USB
* Fixes [SkyStone issue #9](https://github.com/FIRST-Tech-Challenge/SkyStone/issues/9)
* Fixes [ftc_app issue #715](https://github.com/ftctechnh/ftc_app/issues/715)
* Prevents extra DS User clicks by filtering based on current state.
* Prevents incorrect DS UI state changes when receiving new OpMode list from RC
* Adds support for REV Color Sensor V3
* Adds a manual-refresh DS Camera Stream for remotely viewing RC camera frames.
* To show the stream on the DS, initialize **but do not run** a stream-enabled opmode, select the Camera Stream option in the DS menu, and tap the image to refresh. This feature is automatically enabled when using Vuforia or TFOD—no additional RC configuration is required for typical use cases. To hide the stream, select the same menu item again.
* Note that gamepads are disabled and the selected opmode cannot be started while the stream is open as a safety precaution.
* To use custom streams, consult the API docs for `CameraStreamServer#setSource` and `CameraStreamSource`.
* Adds many Star Wars sounds to RobotController resources.
* Added SKYSTONE Sounds Chooser Sample Program.
* Switches out startup, connect chimes, and error/warning sounds for Star Wars sounds
* Updates OnBot Java to use a WebSocket for communication with the robot
* The OnBot Java page no longer has to do a full refresh when a user switches from editing one file to another
Known issues:
* Camera Stream
* The Vuforia camera stream inherits the issues present in the phone preview (namely [ftc_app issue #574](https://github.com/ftctechnh/ftc_app/issues/574)). This problem does not affect the TFOD camera stream even though it receives frames from Vuforia.
* The orientation of the stream frames may not always match the phone preview. For now, these frames may be rotated manually via a custom `CameraStreamSource` if desired.
* OnBotJava
* Browser back button may not always work correctly
* It's possible for a build to be queued, but not started. The OnBot Java build console will display a warning if this occurs.
* A user might not realize they are editing a different file if the user inadvertently switches from one file to another since this switch is now seamless. The name of the currently open file is displayed in the browser tab.
## Version 5.0 (built on 19.06.14)
* Support for the REV Robotics Control Hub.
* Adds a Java preview pane to the Blocks editor.
* Adds a new offline export feature to the Blocks editor.
* Display wifi channel in Network circle on Driver Station.
* Adds calibration for Logitech C270
* Updates build tooling and target SDK.
* Compliance with Google's permissions infrastructure (Required after build tooling update).
* Keep Alives to mitigate the Motorola wifi scanning problem. Telemetry substitute no longer necessary.
* Improves Vuforia error reporting.
* Fixes ftctechnh/ftc_app issues 621, 713.
* Miscellaneous bug fixes and improvements.
## Version 4.3 (built on 18.10.31)
* Includes missing TensorFlow-related libraries and files.
## Version 4.2 (built on 18.10.30)
* Includes fix to avoid deadlock situation with WatchdogMonitor which could result in USB communication errors.
- Comm error appeared to require that user disconnect USB cable and restart the Robot Controller app to recover.
- robotControllerLog.txt would have error messages that included the words "E RobotCore: lynx xmit lock: #### abandoning lock:"
* Includes fix to correctly list the parent module address for a REV Robotics Expansion Hub in a configuration (.xml) file.
- Bug in versions 4.0 and 4.1 would incorrect list the address module for a parent REV Robotics device as "1".
- If the parent module had a higher address value than the daisy-chained module, then this bug would prevent the Robot Controller from communicating with the downstream Expansion Hub.
* Added requirement for ACCESS_COARSE_LOCATION to allow a Driver Station running Android Oreo to scan for Wi-Fi Direct devices.
* Added google() repo to build.gradle because aapt2 must be downloaded from the google() repository beginning with version 3.2 of the Android Gradle Plugin.
- Important Note: Android Studio users will need to be connected to the Internet the first time build the ftc_app project.
- Internet connectivity is required for the first build so the appropriate files can be downloaded from the Google repository.
- Users should not need to be connected to the Internet for subsequent builds.
- This should also fix buid issue where Android Studio would complain that it "Could not find com.android.tools.lint:lint-gradle:26.1.4" (or similar).
* Added support for REV Spark Mini motor controller as part of the configuration menu for a servo/PWM port on the REV Expansion Hub.
* Provide examples for playing audio files in an Op Mode.
* Block Development Tool Changes
- Includes a fix for a problem with the Velocity blocks that were reported in the FTC Technology forum (Blocks Programming subforum).
- Change the "Save completed successfully." message to a white color so it will contrast with a green background.
- Fixed the "Download image" feature so it will work if there are text blocks in the op mode.
* Introduce support for Google's TensorFlow Lite technology for object detetion for 2018-2019 game.
- TensorFlow lite can recognize Gold Mineral and Silver Mineral from 2018-2019 game.
- Example Java and Block op modes are included to show how to determine the relative position of the gold block (left, center, right).
## Version 4.1 (released on 18.09.24)
Changes include:
* Fix to prevent crash when deprecated configuration annotations are used.
* Change to allow FTC Robot Controller APK to be auto-updated using FIRST Global Control Hub update scripts.
* Removed samples for non supported / non legal hardware.
* Improvements to Telemetry.addData block with "text" socket.
* Updated Blocks sample op mode list to include Rover Ruckus Vuforia example.
* Update SDK library version number.
## Version 4.0 (released on 18.09.12)
Changes include:
* 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.
## Version 3.6 (built on 17.12.18)
Changes include:
* Blocks Changes
- Uses updated Google Blockly software to allow users to edit their op modes on Apple iOS devices (including iPad and iPhone).
- Improvement in Blocks tool to handle corrupt op mode files.
- Autonomous op modes should no longer get switched back to tele-op after re-opening them to be edited.
- The system can now detect type mismatches during runtime and alert the user with a message on the Driver Station.
* Updated javadoc documentation for setPower() method to reflect correct range of values (-1 to +1).
* Modified VuforiaLocalizerImpl to allow for user rendering of frames
- Added a user-overrideable onRenderFrame() method which gets called by the class's renderFrame() method.
## Version 3.5 (built on 17.10.30)
Changes with version 3.5 include:
* Introduced a fix to prevent random op mode stops, which can occur after the Robot Controller app has been paused and then resumed (for example, when a user temporarily turns off the display of the Robot Controller phone, and then turns the screen back on).
* Introduced a fix to prevent random op mode stops, which were previously caused by random peer disconnect events on the Driver Station.
* Fixes issue where log files would be closed on pause of the RC or DS, but not re-opened upon resume.
* Fixes issue with battery handler (voltage) start/stop race.
* Fixes issue where Android Studio generated op modes would disappear from available list in certain situations.
* Fixes problem where OnBot Java would not build on REV Robotics Control Hub.
* Fixes problem where OnBot Java would not build if the date and time on the Robot Controller device was "rewound" (set to an earlier date/time).
* Improved error message on OnBot Java that occurs when renaming a file fails.
* Removed unneeded resources from android.jar binaries used by OnBot Java to reduce final size of Robot Controller app.
* Added MR_ANALOG_TOUCH_SENSOR block to Blocks Programming Tool.
## Version 3.4 (built on 17.09.06)
Changes with version 3.4 include:
* Added telemetry.update() statement for BlankLinearOpMode template.
* Renamed sample Block op modes to be more consistent with Java samples.
* Added some additional sample Block op modes.
* Reworded OnBot Java readme slightly.
## Version 3.3 (built on 17.09.04)
This version of the software includes improves for the FTC Blocks Programming Tool and the OnBot Java Programming Tool.
Changes with verion 3.3 include:
* Android Studio ftc_app project has been updated to use Gradle Plugin 2.3.3.
* Android Studio ftc_app project is already using gradle 3.5 distribution.
* Robot Controller log has been renamed to /sdcard/RobotControllerLog.txt (note that this change was actually introduced w/ v3.2).
* Improvements in I2C reliability.
* Optimized I2C read for REV Expansion Hub, with v1.7 firmware or greater.
* Updated all external/samples (available through OnBot and in Android project folder).
* Vuforia
- Added support for VuMarks that will be used for the 2017-2018 season game.
* Blocks
- Update to latest Google Blockly release.
- Sample op modes can be selected as a template when creating new op mode.
- Fixed bug where the blocks would disappear temporarily when mouse button is held down.
- Added blocks for Range.clip and Range.scale.
- User can now disable/enable Block op modes.
- Fix to prevent occasional Blocks deadlock.
* OnBot Java
- Significant improvements with autocomplete function for OnBot Java editor.
- Sample op modes can be selected as a template when creating new op mode.
- Fixes and changes to complete hardware setup feature.
- Updated (and more useful) onBot welcome message.
Known issues:
* Android Studio
- After updating to the new v3.3 Android Studio project folder, if you get error messages indicating "InvalidVirtualFileAccessException" then you might need to do a File->Invalidate Caches / Restart to clear the error.
* OnBot Java
- Sometimes when you push the build button to build all op modes, the RC returns an error message that the build failed. If you press the build button a second time, the build typically suceeds.
## Version 3.2 (built on 17.08.02)
This version of the software introduces the "OnBot Java" Development Tool. Similar to the FTC Blocks Development Tool, the FTC OnBot Java Development Tool allows a user to create, edit and build op modes dynamically using only a Javascript-enabled web browser.
The OnBot Java Development Tool is an integrated development environment (IDE) that is served up by the Robot Controller. Op modes are created and edited using a Javascript-enabled browser (Google Chromse is recommended). Op modes are saved on the Robot Controller Android device directly.
The OnBot Java Development Tool provides a Java programming environment that does NOT need Android Studio.
Changes with version 3.2 include:
* Enhanced web-based development tools
- Introduction of OnBot Java Development Tool.
- Web-based programming and management features are "always on" (user no longer needs to put Robot Controller into programming mode).
- Web-based management interface (where user can change Robot Controller name and also easily download Robot Controller log file).
- OnBot Java, Blocks and Management features available from web based interface.
* Blocks Programming Development Tool:
- Changed "LynxI2cColorRangeSensor" block to "REV Color/range sensor" block.
- Fixed tooltip for ColorSensor.isLightOn block.
Added blocks for ColorSensor.getNormalizedColors and LynxI2cColorRangeSensor.getNormalizedColors.
* Added example op modes for digital touch sensor and REV Robotics Color Distance sensor.
* User selectable color themes.
* Includes many minor enhancements and fixes (too numerous to list).
Known issues:
* Auto complete function is incomplete and does not support the following (for now):
- Access via *this* keyword
- Access via *super* keyword
- Members of the super cloass, not overridden by the class
- Any methods provided in the current class
- Inner classes
- Can't handle casted objects
- Any objects coming from an parenthetically enclosed expression
## Version 3.10 (built on 17.05.09)
This version of the software provides support for the REV Robotics Expansion Hub. This version also includes improvements in the USB communication layer in an effort to enhance system resiliency. If you were using a 2.x version of the software previously, updating to version 3.1 requires that you also update your Driver Station software in addition to updating the Robot Controller software.
Also note that in version 3.10 software, the setMaxSpeed and getMaxSpeed methods are no longer available (not deprecated, they have been removed from the SDK). Also note that the the new 3.x software incorporates motor profiles that a user can select as he/she configures the robot.
Changes include:
* Blocks changes
- Added VuforiaTrackableDefaultListener.getPose and Vuforia.trackPose blocks.
- Added optimized blocks support for Vuforia extended tracking.
- Added atan2 block to the math category.
- Added useCompetitionFieldTargetLocations parameter to Vuforia.initialize block. If set to false, the target locations are placed at (0,0,0) with target orientation as specified in https://github.com/gearsincorg/FTCVuforiaDemo/blob/master/Robot_Navigation.java tutorial op mode.
* Incorporates additional improvements to USB comm layer to improve system resiliency (to recover from a greater number of communication disruptions).
**************************************************************************************
Additional Notes Regarding Version 3.00 (built on 17.04.13)
In addition to the release changes listed below (see section labeled "Version 3.00 (built on 17.04.013)"), version 3.00 has the following important changes:
1. Version 3.00 software uses a new version of the FTC Robocol (robot protocol). If you upgrade to v3.0 on the Robot Controller and/or Android Studio side, you must also upgrade the Driver Station software to match the new Robocol.
2. Version 3.00 software removes the setMaxSpeed and getMaxSpeed methods from the DcMotor class. If you have an op mode that formerly used these methods, you will need to remove the references/calls to these methods. Instead, v3.0 provides the max speed information through the use of motor profiles that are selected by the user during robot configuration.
3. Version 3.00 software currently does not have a mechanism to disable extra i2c sensors. We hope to re-introduce this function with a release in the near future.
**************************************************************************************
## Version 3.00 (built on 17.04.13)
*** Use this version of the software at YOUR OWN RISK!!! ***
This software is being released as an "alpha" version. Use this version at your own risk!
This pre-release software contains SIGNIFICANT changes, including changes to the Wi-Fi Direct pairing mechanism, rewrites of the I2C sensor classes, changes to the USB/FTDI layer, and the introduction of support for the REV Robotics Expansion Hub and the REV Robotics color-range-light sensor. These changes were implemented to improve the reliability and resiliency of the FTC control system.
Please note, however, that version 3.00 is considered "alpha" code. This code is being released so that the FIRST community will have an opportunity to test the new REV Expansion Hub electronics module when it becomes available in May. The developers do not recommend using this code for critical applications (i.e., competition use).
*** Use this version of the software at YOUR OWN RISK!!! ***
Changes include:
* Major rework of sensor-related infrastructure. Includes rewriting sensor classes to implement synchronous I2C communication.
* Fix to reset Autonomous timer back to 30 seconds.
* Implementation of specific motor profiles for approved 12V motors (includes Tetrix, AndyMark, Matrix and REV models).
* Modest improvements to enhance Wi-Fi P2P pairing.
* Fixes telemetry log addition race.
* Publishes all the sources (not just a select few).
* Includes Block programming improvements
- Addition of optimized Vuforia blocks.
- Auto scrollbar to projects and sounds pages.
- Fixed blocks paste bug.
- Blocks execute after while-opModeIsActive loop (to allow for cleanup before exiting op mode).
- Added gyro integratedZValue block.
- Fixes bug with projects page for Firefox browser.
- Added IsSpeaking block to AndroidTextToSpeech.
* Implements support for the REV Robotics Expansion Hub
- Implements support for integral REV IMU (physically installed on I2C bus 0, uses same Bosch BNO055 9 axis absolute orientation sensor as Adafruit 9DOF abs orientation sensor). - Implements support for REV color/range/light sensor.
- Provides support to update Expansion Hub firmware through FTC SDK.
- Detects REV firmware version and records in log file.
- Includes support for REV Control Hub (note that the REV Control Hub is not yet approved for FTC use).
- Implements FTC Blocks programming support for REV Expansion Hub and sensor hardware.
- Detects and alerts when I2C device disconnect.
## Version 2.62 (built on 17.01.07)
* Added null pointer check before calling modeToByte() in finishModeSwitchIfNecessary method for ModernRoboticsUsbDcMotorController class.
* Changes to enhance Modern Robotics USB protocol robustness.
## Version 2.61 (released on 16.12.19)
* Blocks Programming mode changes:
- Fix to correct issue when an exception was thrown because an OpticalDistanceSensor object appears twice in the hardware map (the second time as a LightSensor).
## Version 2.6 (released on 16.12.16)
* Fixes for Gyro class:
- Improve (decrease) sensor refresh latency.
- fix isCalibrating issues.
* Blocks Programming mode changes:
- Blocks now ignores a device in the configuration xml if the name is empty. Other devices work in configuration work fine.
## Version 2.5 (internal release on released on 16.12.13)
* Blocks Programming mode changes:
- Added blocks support for AdafruitBNO055IMU.
- Added Download Op Mode button to FtcBocks.html.
- Added support for copying blocks in one OpMode and pasting them in an other OpMode. The clipboard content is stored on the phone, so the programming mode server must be running.
- Modified Utilities section of the toolbox.
- In Programming Mode, display information about the active connections.
- Fixed paste location when workspace has been scrolled.
- Added blocks support for the android Accelerometer.
- Fixed issue where Blocks Upload Op Mode truncated name at first dot.
- Added blocks support for Android SoundPool.
- Added type safety to blocks for Acceleration.
- Added type safety to blocks for AdafruitBNO055IMU.Parameters.
- Added type safety to blocks for AnalogInput.
- Added type safety to blocks for AngularVelocity.
- Added type safety to blocks for Color.
- Added type safety to blocks for ColorSensor.
- Added type safety to blocks for CompassSensor.
- Added type safety to blocks for CRServo.
- Added type safety to blocks for DigitalChannel.
- Added type safety to blocks for ElapsedTime.
- Added type safety to blocks for Gamepad.
- Added type safety to blocks for GyroSensor.
- Added type safety to blocks for IrSeekerSensor.
- Added type safety to blocks for LED.
- Added type safety to blocks for LightSensor.
- Added type safety to blocks for LinearOpMode.
- Added type safety to blocks for MagneticFlux.
- Added type safety to blocks for MatrixF.
- Added type safety to blocks for MrI2cCompassSensor.
- Added type safety to blocks for MrI2cRangeSensor.
- Added type safety to blocks for OpticalDistanceSensor.
- Added type safety to blocks for Orientation.
- Added type safety to blocks for Position.
- Added type safety to blocks for Quaternion.
- Added type safety to blocks for Servo.
- Added type safety to blocks for ServoController.
- Added type safety to blocks for Telemetry.
- Added type safety to blocks for Temperature.
- Added type safety to blocks for TouchSensor.
- Added type safety to blocks for UltrasonicSensor.
- Added type safety to blocks for VectorF.
- Added type safety to blocks for Velocity.
- Added type safety to blocks for VoltageSensor.
- Added type safety to blocks for VuforiaLocalizer.Parameters.
- Added type safety to blocks for VuforiaTrackable.
- Added type safety to blocks for VuforiaTrackables.
- Added type safety to blocks for enums in AdafruitBNO055IMU.Parameters.
- Added type safety to blocks for AndroidAccelerometer, AndroidGyroscope, AndroidOrientation, and AndroidTextToSpeech.
## Version 2.4 (released on 16.11.13)
* Fix to avoid crashing for nonexistent resources.
* Blocks Programming mode changes:
- Added blocks to support OpenGLMatrix, MatrixF, and VectorF.
- Added blocks to support AngleUnit, AxesOrder, AxesReference, CameraDirection, CameraMonitorFeedback, DistanceUnit, and TempUnit.
- Added blocks to support Acceleration.
- Added blocks to support LinearOpMode.getRuntime.
- Added blocks to support MagneticFlux and Position.
- Fixed typos.
- Made blocks for ElapsedTime more consistent with other objects.
- Added blocks to support Quaternion, Velocity, Orientation, AngularVelocity.
- Added blocks to support VuforiaTrackables, VuforiaTrackable, VuforiaLocalizer, VuforiaTrackableDefaultListener.
- Fixed a few blocks.
- Added type checking to new blocks.
- Updated to latest blockly.
- Added default variable blocks to navigation and matrix blocks.
- Fixed toolbox entry for openGLMatrix_rotation_withAxesArgs.
- When user downloads Blocks-generated op mode, only the .blk file is downloaded.
- When user uploads Blocks-generated op mode (.blk file), Javascript code is auto generated.
- Added DbgLog support.
- Added logging when a blocks file is read/written.
- Fixed bug to properly render blocks even if missing devices from configuration file.
- Added support for additional characters (not just alphanumeric) for the block file names (for download and upload).
- Added support for OpMode flavor (“Autonomous” or “TeleOp”) and group.
* Changes to Samples to prevent tutorial issues.
* Incorporated suggested changes from public pull 216 (“Replace .. paths”).
* Remove Servo Glitches when robot stopped.
* if user hits “Cancels” when editing a configuration file, clears the unsaved changes and reverts to original unmodified configuration.
* Added log info to help diagnose why the Robot Controller app was terminated (for example, by watch dog function).
* Added ability to transfer log from the controller.
* Fixed inconsistency for AngularVelocity
* Limit unbounded growth of data for telemetry. If user does not call telemetry.update() for LinearOpMode in a timely manner, data added for telemetry might get lost if size limit is exceeded.
## Version 2.35 (released on 16.10.06)
* Blockly programming mode - Removed unnecesary idle() call from blocks for new project.
## Version 2.30 (released on 16.10.05)
* Blockly programming mode:
- Mechanism added to save Blockly op modes from Programming Mode Server onto local device
- To avoid clutter, blocks are displayed in categorized folders
- Added support for DigitalChannel
- Added support for ModernRoboticsI2cCompassSensor
- Added support for ModernRoboticsI2cRangeSensor
- Added support for VoltageSensor
- Added support for AnalogInput
- Added support for AnalogOutput
- Fix for CompassSensor setMode block
* Vuforia
- Fix deadlock / make camera data available while Vuforia is running.
- Update to Vuforia 6.0.117 (recommended by Vuforia and Google to close security loophole).
* Fix for autonomous 30 second timer bug (where timer was in effect, even though it appeared to have timed out).
* opModeIsActive changes to allow cleanup after op mode is stopped (with enforced 2 second safety timeout).
* Fix to avoid reading i2c twice.
* Updated sample Op Modes.
* Improved logging and fixed intermittent freezing.
* Added digital I/O sample.
* Cleaned up device names in sample op modes to be consistent with Pushbot guide.
* Fix to allow use of IrSeekerSensorV3.
## Version 2.20 (released on 16.09.08)
* Support for Modern Robotics Compass Sensor.
* Support for Modern Robotics Range Sensor.
* Revise device names for Pushbot templates to match the names used in Pushbot guide.
* Fixed bug so that IrSeekerSensorV3 device is accessible as IrSeekerSensor in hardwareMap.
* Modified computer vision code to require an individual Vuforia license (per legal requirement from PTC).
* Minor fixes.
* Blockly enhancements:
- Support for Voltage Sensor.
- Support for Analog Input.
- Support for Analog Output.
- Support for Light Sensor.
- Support for Servo Controller.
## Version 2.10 (released on 16.09.03)
* Support for Adafruit IMU.
* Improvements to ModernRoboticsI2cGyro class
- Block on reset of z axis.
- isCalibrating() returns true while gyro is calibration.
* Updated sample gyro program.
* Blockly enhancements
- support for android.graphics.Color.
- added support for ElapsedTime.
- improved look and legibility of blocks.
- support for compass sensor.
- support for ultrasonic sensor.
- support for IrSeeker.
- support for LED.
- support for color sensor.
- support for CRServo
- prompt user to configure robot before using programming mode.
* Provides ability to disable audio cues.
* various bug fixes and improvements.
## Version 2.00 (released on 16.08.19)
* This is the new release for the upcoming 2016-2017 FIRST Tech Challenge Season.
* Channel change is enabled in the FTC Robot Controller app for Moto G 2nd and 3rd Gen phones.
* Users can now use annotations to register/disable their Op Modes.
* Changes in the Android SDK, JDK and build tool requirements (minsdk=19, java 1.7, build tools 23.0.3).
* Standardized units in analog input.
* Cleaned up code for existing analog sensor classes.
* setChannelMode and getChannelMode were REMOVED from the DcMotorController class. This is important - we no longer set the motor modes through the motor controller.
* setMode and getMode were added to the DcMotor class.
* ContinuousRotationServo class has been added to the FTC SDK.
* Range.clip() method has been overloaded so it can support this operation for int, short and byte integers.
* Some changes have been made (new methods added) on how a user can access items from the hardware map.
* Users can now set the zero power behavior for a DC motor so that the motor will brake or float when power is zero.
* Prototype Blockly Programming Mode has been added to FTC Robot Controller. Users can place the Robot Controller into this mode, and then use a device (such as a laptop) that has a Javascript enabled browser to write Blockly-based Op Modes directly onto the Robot Controller.
* Users can now configure the robot remotely through the FTC Driver Station app.
* Android Studio project supports Android Studio 2.1.x and compile SDK Version 23 (Marshmallow).
* Vuforia Computer Vision SDK integrated into FTC SDK. Users can use sample vision targets to get localization information on a standard FTC field.
* Project structure has been reorganized so that there is now a TeamCode package that users can use to place their local/custom Op Modes into this package.
* Inspection function has been integrated into the FTC Robot Controller and Driver Station Apps (Thanks Team HazMat… 9277 & 10650!).
* Audio cues have been incorporated into FTC SDK.
* Swap mechanism added to FTC Robot Controller configuration activity. For example, if you have two motor controllers on a robot, and you misidentified them in your configuration file, you can use the Swap button to swap the devices within the configuration file (so you do not have to manually re-enter in the configuration info for the two devices).
* Fix mechanism added to all user to replace an electronic module easily. For example, suppose a servo controller dies on your robot. You replace the broken module with a new module, which has a different serial number from the original servo controller. You can use the Fix button to automatically reconfigure your configuration file to use the serial number of the new module.
* Improvements made to fix resiliency and responsiveness of the system.
* For LinearOpMode the user now must for a telemetry.update() to update the telemetry data on the driver station. This update() mechanism ensures that the driver station gets the updated data properly and at the same time.
* The Auto Configure function of the Robot Controller is now template based. If there is a commonly used robot configuration, a template can be created so that the Auto Configure mechanism can be used to quickly configure a robot of this type.
* The logic to detect a runaway op mode (both in the LinearOpMode and OpMode types) and to abort the run, then auto recover has been improved/implemented.
* Fix has been incorporated so that Logitech F310 gamepad mappings will be correct for Marshmallow users.
## Release 16.07.08
* For the ftc_app project, the gradle files have been modified to support Android Studio 2.1.x.
## Release 16.03.30
* For the MIT App Inventor, the design blocks have new icons that better represent the function of each design component.
* Some changes were made to the shutdown logic to ensure the robust shutdown of some of our USB services.
* A change was made to LinearOpMode so as to allow a given instance to be executed more than once, which is required for the App Inventor.
* Javadoc improved/updated.
## Release 16.03.09
* Changes made to make the FTC SDK synchronous (significant change!)
- waitOneFullHardwareCycle() and waitForNextHardwareCycle() are no longer needed and have been deprecated.
- runOpMode() (for a LinearOpMode) is now decoupled from the system's hardware read/write thread.
- loop() (for an OpMode) is now decoupled from the system's hardware read/write thread.
- Methods are synchronous.
- For example, if you call setMode(DcMotorController.RunMode.RESET_ENCODERS) for a motor, the encoder is guaranteed to be reset when the method call is complete.
- For legacy module (NXT compatible), user no longer has to toggle between read and write modes when reading from or writing to a legacy device.
* Changes made to enhance reliability/robustness during ESD event.
* Changes made to make code thread safe.
* Debug keystore added so that user-generated robot controller APKs will all use the same signed key (to avoid conflicts if a team has multiple developer laptops for example).
* Firmware version information for Modern Robotics modules are now logged.
* Changes made to improve USB comm reliability and robustness.
* Added support for voltage indicator for legacy (NXT-compatible) motor controllers.
* Changes made to provide auto stop capabilities for op modes.
- A LinearOpMode class will stop when the statements in runOpMode() are complete. User does not have to push the stop button on the driver station.
- If an op mode is stopped by the driver station, but there is a run away/uninterruptible thread persisting, the app will log an error message then force itself to crash to stop the runaway thread.
* Driver Station UI modified to display lowest measured voltage below current voltage (12V battery).
* Driver Station UI modified to have color background for current voltage (green=good, yellow=caution, red=danger, extremely low voltage).
* javadoc improved (edits and additional classes).
* Added app build time to About activity for driver station and robot controller apps.
* Display local IP addresses on Driver Station About activity.
* Added I2cDeviceSynchImpl.
* Added I2cDeviceSync interface.
* Added seconds() and milliseconds() to ElapsedTime for clarity.
* Added getCallbackCount() to I2cDevice.
* Added missing clearI2cPortActionFlag.
* Added code to create log messages while waiting for LinearOpMode shutdown.
* Fix so Wifi Direct Config activity will no longer launch multiple times.
* Added the ability to specify an alternate i2c address in software for the Modern Robotics gyro.
## Release 16.02.09
* Improved battery checker feature so that voltage values get refreshed regularly (every 250 msec) on Driver Station (DS) user interface.
* Improved software so that Robot Controller (RC) is much more resilient and “self-healing” to USB disconnects:
- If user attempts to start/restart RC with one or more module missing, it will display a warning but still start up.
- When running an op mode, if one or more modules gets disconnected, the RC & DS will display warnings,and robot will keep on working in spite of the missing module(s).
- If a disconnected module gets physically reconnected the RC will auto detect the module and the user will regain control of the recently connected module.
- Warning messages are more helpful (identifies the type of module that’s missing plus its USB serial number).
* Code changes to fix the null gamepad reference when users try to reference the gamepads in the init() portion of their op mode.
* NXT light sensor output is now properly scaled. Note that teams might have to readjust their light threshold values in their op modes.
* On DS user interface, gamepad icon for a driver will disappear if the matching gamepad is disconnected or if that gamepad gets designated as a different driver.
* Robot Protocol (ROBOCOL) version number info is displayed in About screen on RC and DS apps.
* Incorporated a display filter on pairing screen to filter out devices that don’t use the “-“ format. This filter can be turned off to show all WiFi Direct devices.
* Updated text in License file.
* Fixed formatting error in OpticalDistanceSensor.toString().
* Fixed issue on with a blank (“”) device name that would disrupt WiFi Direct Pairing.
* Made a change so that the WiFi info and battery info can be displayed more quickly on the DS upon connecting to RC.
* Improved javadoc generation.
* Modified code to make it easier to support language localization in the future.
## Release 16.01.04
* Updated compileSdkVersion for apps
* Prevent Wifi from entering power saving mode
* removed unused import from driver station
* Corrrected "Dead zone" joystick code.
* LED.getDeviceName and .getConnectionInfo() return null
* apps check for ROBOCOL_VERSION mismatch
* Fix for Telemetry also has off-by-one errors in its data string sizing / short size limitations error
* User telemetry output is sorted.
* added formatting variants to DbgLog and RobotLog APIs
* code modified to allow for a long list of op mode names.
* changes to improve thread safety of RobocolDatagramSocket
* Fix for "missing hardware leaves robot controller disconnected from driver station" error
* fix for "fast tapping of Init/Start causes problems" (toast is now only instantiated on UI thread).
* added some log statements for thread life cycle.
* moved gamepad reset logic inside of initActiveOpMode() for robustness
* changes made to mitigate risk of race conditions on public methods.
* changes to try and flag when WiFi Direct name contains non-printable characters.
* fix to correct race condition between .run() and .close() in ReadWriteRunnableStandard.
* updated FTDI driver
* made ReadWriteRunnableStanard interface public.
* fixed off-by-one errors in Command constructor
* moved specific hardware implmentations into their own package.
* moved specific gamepad implemnatations to the hardware library.
* changed LICENSE file to new BSD version.
* fixed race condition when shutting down Modern Robotics USB devices.
* methods in the ColorSensor classes have been synchronized.
* corrected isBusy() status to reflect end of motion.
* corrected "back" button keycode.
* the notSupported() method of the GyroSensor class was changed to protected (it should not be public).
## Release 15.11.04.001
* Added Support for Modern Robotics Gyro.
- The GyroSensor class now supports the MR Gyro Sensor.
- Users can access heading data (about Z axis)
- Users can also access raw gyro data (X, Y, & Z axes).
- Example MRGyroTest.java op mode included.
* Improved error messages
- More descriptive error messages for exceptions in user code.
* Updated DcMotor API
* Enable read mode on new address in setI2cAddress
* Fix so that driver station app resets the gamepads when switching op modes.
* USB-related code changes to make USB comm more responsive and to display more explicit error messages.
- Fix so that USB will recover properly if the USB bus returns garbage data.
- Fix USB initializtion race condition.
- Better error reporting during FTDI open.
- More explicit messages during USB failures.
- Fixed bug so that USB device is closed if event loop teardown method was not called.
* Fixed timer UI issue
* Fixed duplicate name UI bug (Legacy Module configuration).
* Fixed race condition in EventLoopManager.
* Fix to keep references stable when updating gamepad.
* For legacy Matrix motor/servo controllers removed necessity of appending "Motor" and "Servo" to controller names.
* Updated HT color sensor driver to use constants from ModernRoboticsUsbLegacyModule class.
* Updated MR color sensor driver to use constants from ModernRoboticsUsbDeviceInterfaceModule class.
* Correctly handle I2C Address change in all color sensors
* Updated/cleaned up op modes.
- Updated comments in LinearI2cAddressChange.java example op mode.
- Replaced the calls to "setChannelMode" with "setMode" (to match the new of the DcMotor method).
- Removed K9AutoTime.java op mode.
- Added MRGyroTest.java op mode (demonstrates how to use MR Gyro Sensor).
- Added MRRGBExample.java op mode (demonstrates how to use MR Color Sensor).
- Added HTRGBExample.java op mode (demonstrates how to use HT legacy color sensor).
- Added MatrixControllerDemo.java (demonstrates how to use legacy Matrix controller).
* Updated javadoc documentation.
* Updated release .apk files for Robot Controller and Driver Station apps.
## Release 15.10.06.002
* Added support for Legacy Matrix 9.6V motor/servo controller.
* Cleaned up build.gradle file.
* Minor UI and bug fixes for driver station and robot controller apps.
* Throws error if Ultrasonic sensor (NXT) is not configured for legacy module port 4 or 5.
## Release 15.08.03.001
* New user interfaces for FTC Driver Station and FTC Robot Controller apps.
* An init() method is added to the OpMode class.
- For this release, init() is triggered right before the start() method.
- Eventually, the init() method will be triggered when the user presses an "INIT" button on driver station.
- The init() and loop() methods are now required (i.e., need to be overridden in the user's op mode).
- The start() and stop() methods are optional.
* A new LinearOpMode class is introduced.
- Teams can use the LinearOpMode mode to create a linear (not event driven) program model.
- Teams can use blocking statements like Thread.sleep() within a linear op mode.
* The API for the Legacy Module and Core Device Interface Module have been updated.
- Support for encoders with the Legacy Module is now working.
* The hardware loop has been updated for better performance.
================================================
FILE: TeamCode/build.gradle
================================================
//
// build.gradle in TeamCode
//
// Most of the definitions for building your module reside in a common, shared
// file 'build.common.gradle'. Being factored in this way makes it easier to
// integrate updates to the FTC into your code. If you really need to customize
// the build definitions, you can place those customizations in this file, but
// please think carefully as to whether such customizations are really necessary
// before doing so.
// Custom definitions may go here
// Include common definitions from above.
apply from: '../build.common.gradle'
repositories {
maven { url = "https://dl.bintray.com/first-tech-challenge/ftcsdk/" }
}
dependencies {
annotationProcessor files('lib/OpModeAnnotationProcessor.jar')
}
================================================
FILE: TeamCode/build.release.gradle
================================================
dependencies {
implementation project(':FtcRobotController')
implementation 'org.firstinspires.ftc:RobotCore:5.5'
implementation 'org.firstinspires.ftc:Hardware:5.5'
implementation 'org.firstinspires.ftc:FtcCommon:5.5'
implementation (name: 'WirelessP2p-release', ext:'aar')
implementation (name: 'tfod-release', ext:'aar')
implementation (name: 'tensorflow-lite-0.0.0-nightly', ext:'aar')
}
================================================
FILE: TeamCode/src/main/AndroidManifest.xml
================================================
================================================
FILE: TeamCode/src/main/java/org/firstinspires/ftc/teamcode/readme.md
================================================
## TeamCode Module
Welcome!
This module, TeamCode, is the place where you will write/paste the code for your team's
robot controller App. This module is currently empty (a clean slate) but the
process for adding OpModes is straightforward.
## Creating your own OpModes
The easiest way to create your own OpMode is to copy a Sample OpMode and make it your own.
Sample opmodes exist in the FtcRobotController module.
To locate these samples, find the FtcRobotController module in the "Project/Android" tab.
Expand the following tree elements:
FtcRobotController / java / org.firstinspires.ftc.robotcontroller / external / samples
A range of different samples classes can be seen in this folder.
The class names follow a naming convention which indicates the purpose of each class.
The full description of this convention is found in the samples/sample_convention.md file.
A brief synopsis of the naming convention is given here:
The prefix of the name will be one of the following:
* Basic: This is a minimally functional OpMode used to illustrate the skeleton/structure
of a particular style of OpMode. These are bare bones examples.
* Sensor: This is a Sample OpMode that shows how to use a specific sensor.
It is not intended as a functioning robot, it is simply showing the minimal code
required to read and display the sensor values.
* Hardware: This is not an actual OpMode, but a helper class that is used to describe
one particular robot's hardware devices: eg: for a Pushbot. Look at any
Pushbot sample to see how this can be used in an OpMode.
Teams can copy one of these to create their own robot definition.
* Pushbot: This is a Sample OpMode that uses the Pushbot robot structure as a base.
* Concept: This is a sample OpMode that illustrates performing a specific function or concept.
These may be complex, but their operation should be explained clearly in the comments,
or the header should reference an external doc, guide or tutorial.
* Library: This is a class, or set of classes used to implement some strategy.
These will typically NOT implement a full OpMode. Instead they will be included
by an OpMode to provide some stand-alone capability.
Once you are familiar with the range of samples available, you can choose one to be the
basis for your own robot. In all cases, the desired sample(s) needs to be copied into
your TeamCode module to be used.
This is done inside Android Studio directly, using the following steps:
1) Locate the desired sample class in the Project/Android tree.
2) Right click on the sample class and select "Copy"
3) Expand the TeamCode / java folder
4) Right click on the org.firstinspires.ftc.teamcode folder and select "Paste"
5) You will be prompted for a class name for the copy.
Choose something meaningful based on the purpose of this class.
Start with a capital letter, and remember that there may be more similar classes later.
Once your copy has been created, you should prepare it for use on your robot.
This is done by adjusting the OpMode's name, and enabling it to be displayed on the
Driver Station's OpMode list.
Each OpMode sample class begins with several lines of code like the ones shown below:
```
@TeleOp(name="Template: Linear OpMode", group="Linear Opmode")
@Disabled
```
The name that will appear on the driver station's "opmode list" is defined by the code:
``name="Template: Linear OpMode"``
You can change what appears between the quotes to better describe your opmode.
The "group=" portion of the code can be used to help organize your list of OpModes.
As shown, the current OpMode will NOT appear on the driver station's OpMode list because of the
``@Disabled`` annotation which has been included.
This line can simply be deleted , or commented out, to make the OpMode visible.
## ADVANCED Multi-Team App management: Cloning the TeamCode Module
In some situations, you have multiple teams in your club and you want them to all share
a common code organization, with each being able to *see* the others code but each having
their own team module with their own code that they maintain themselves.
In this situation, you might wish to clone the TeamCode module, once for each of these teams.
Each of the clones would then appear along side each other in the Android Studio module list,
together with the FtcRobotController module (and the original TeamCode module).
Selective Team phones can then be programmed by selecting the desired Module from the pulldown list
prior to clicking to the green Run arrow.
Warning: This is not for the inexperienced Software developer.
You will need to be comfortable with File manipulations and managing Android Studio Modules.
These changes are performed OUTSIDE of Android Studios, so close Android Studios before you do this.
Also.. Make a full project backup before you start this :)
To clone TeamCode, do the following:
Note: Some names start with "Team" and others start with "team". This is intentional.
1) Using your operating system file management tools, copy the whole "TeamCode"
folder to a sibling folder with a corresponding new name, eg: "Team0417".
2) In the new Team0417 folder, delete the TeamCode.iml file.
3) the new Team0417 folder, rename the "src/main/java/org/firstinspires/ftc/teamcode" folder
to a matching name with a lowercase 'team' eg: "team0417".
4) In the new Team0417/src/main folder, edit the "AndroidManifest.xml" file, change the line that contains
package="org.firstinspires.ftc.teamcode"
to be
package="org.firstinspires.ftc.team0417"
5) Add: include ':Team0417' to the "/settings.gradle" file.
6) Open up Android Studios and clean out any old files by using the menu to "Build/Clean Project""
================================================
FILE: TeamCode/src/main/res/raw/readme.md
================================================
Place your sound files in this folder to use them as project resources.
================================================
FILE: TeamCode/src/main/res/values/strings.xml
================================================
================================================
FILE: TeamCode/src/main/res/xml/teamwebcamcalibrations.xml
================================================
================================================
FILE: build.common.gradle
================================================
/**
* build.common.gradle
*
* Try to avoid editing this file, as it may be updated from time to time as the FTC SDK
* evolves. Rather, if it is necessary to customize the build process, do those edits in
* the build.gradle file in TeamCode.
*
* This file contains the necessary content of the 'build.gradle' files for robot controller
* applications built using the FTC SDK. Each individual 'build.gradle' in those applications
* can simply contain the one line:
*
* apply from: '../build.common.gradle'
*
* which will pick up this file here. This approach allows makes it easier to integrate
* updates to the FTC SDK into your code.
*/
import java.util.regex.Pattern
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
signingConfigs {
debug {
keyAlias 'androiddebugkey'
keyPassword 'android'
storeFile rootProject.file('libs/ftc.debug.keystore')
storePassword 'android'
}
}
aaptOptions {
noCompress "tflite"
}
defaultConfig {
signingConfig signingConfigs.debug
applicationId 'com.qualcomm.ftcrobotcontroller'
minSdkVersion 23
targetSdkVersion 28
/**
* We keep the versionCode and versionName of robot controller applications in sync with
* the master information published in the AndroidManifest.xml file of the FtcRobotController
* module. This helps avoid confusion that might arise from having multiple versions of
* a robot controller app simultaneously installed on a robot controller device.
*
* We accomplish this with the help of a funky little Groovy script that maintains that
* correspondence automatically.
*
* @see Configure Your Build
* @see Versioning Your App
*/
def manifestFile = project(':FtcRobotController').file('src/main/AndroidManifest.xml');
def manifestText = manifestFile.getText()
//
def vCodePattern = Pattern.compile("versionCode=\"(\\d+(\\.\\d+)*)\"")
def matcher = vCodePattern.matcher(manifestText)
matcher.find()
def vCode = Integer.parseInt(matcher.group(1))
//
def vNamePattern = Pattern.compile("versionName=\"(.*)\"")
matcher = vNamePattern.matcher(manifestText);
matcher.find()
def vName = matcher.group(1)
//
versionCode vCode
versionName vName
}
// 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.
//debuggable true
ndk {
abiFilters "armeabi-v7a", "arm64-v8a"
}
}
debug {
debuggable true
jniDebuggable true
renderscriptDebuggable true
ndk {
abiFilters "armeabi-v7a", "arm64-v8a"
}
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir rootProject.file('libs')
}
}
repositories {
flatDir {
dirs rootProject.file('libs')
}
}
apply from: 'build.release.gradle'
================================================
FILE: build.gradle
================================================
/**
* Top-level build file for ftc_app project.
*
* It is extraordinarily rare that you will ever need to edit this file.
*/
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'
}
}
// This is now required because aapt2 has to be downloaded from the
// google() repository beginning with version 3.2 of the Android Gradle Plugin
allprojects {
repositories {
google()
jcenter()
}
}
================================================
FILE: doc/legal/AudioBlocksSounds.txt
================================================
The sound files listed below in this SDK were purchased from www.audioblocks.com under the
following license.
http://support.audioblocks.com/customer/en/portal/topics/610636-licensing-faq-s/articles
How am I allowed to use your content?
Last Updated: Aug 11, 2016 01:51PM EDT
Our content may be used for nearly any project, commercial or otherwise, including feature
films, broadcast, commercial, industrial, educational video, print projects, multimedia,
games, and the internet, so long as substantial value is added to the content. (For example,
incorporating an audio clip into a commercial qualifies, while reposting our audio clip on
YouTube with no modification or no visual component does not.) Once you download a file it is
yours to keep and use forever, royalty- free, even if you change your subscription or cancel
your account.
List of applicable sound files
chimeconnect.wav
chimedisconnect.wav
errormessage.wav
warningmessage.wav
================================================
FILE: doc/legal/Exhibit A - LEGO Open Source License Agreement.txt
================================================
EXHIBIT A - LEGO® Open Source License Agreement
The contents of the file 'nxtstartupsound.wav' contained in this SDK are subject to the
LEGO® Open Source License Agreement Version 1.0 (the "License"); you may not use this
file except in compliance with the License. You may obtain a copy of the License
at "LEGO Open Source License.pdf" contained in the same directory as this exhibit.
Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
WARRANTY OF ANY KIND, either express or implied. See the License for the specific
language governing rights and limitations under the License.
The Original Code is \AT91SAM7S256\Resource\SOUNDS\!Startup.rso.
LEGO is the owner of the Original Code. Portions created by Robert Atkinson are
Copyright (C) 2015. All Rights Reserved.
Contributor(s): Robert Atkinson.
================================================
FILE: doc/media/readme.md
================================================
## Vuforia Localizer Sample Image Targets
The files in this folder are the printable images that correspond to the sample
trackable data sets that have been included with integration of Vuforia to the
FTC SDK. See the ConceptVuforiaNavigation.java OpMode for details.
================================================
FILE: doc/tutorial/README.txt
================================================
What happened to the FTC Software Development Tutorials???
In an effort to save space and reduce download time, the older (and outdated) tutorial documents (FTCTraining_Manual.pdf, FTC_FieldCoordinateSystemDefinition.pdf, FTC_NextGenGuide.pdf, and FTC_ZTE_ChannelChange.pdf) have been removed.
You can find the releveant PDF files attached to the "Releases" page of the GitHub repository:
https://github.com/ftctechnh/ftc_app/releases
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Fri Jul 24 14:30:03 PDT 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
================================================
FILE: gradle.properties
================================================
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
================================================
FILE: gradlew
================================================
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: libs/README.txt
================================================
Location of external libs
================================================
FILE: libs/tfod-release.aar
================================================
[File too large to display: 18.3 MB]
================================================
FILE: settings.gradle
================================================
include ':FtcRobotController'
include ':TeamCode'