Skip to content
This repository was archived by the owner on Sep 12, 2023. It is now read-only.

Commit e98a4cf

Browse files
CalKestiskevinfrei
authored andcommitted
FtcRobotController v7.0
1 parent 673a07b commit e98a4cf

20 files changed

+741
-1040
lines changed

FtcRobotController/build.gradle

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ android {
99

1010
defaultConfig {
1111
minSdkVersion 23
12+
//noinspection ExpiredTargetSdkVersion
1213
targetSdkVersion 28
13-
buildConfigField "String", "BUILD_TIME", '"' + (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.ROOT).format(new Date())) + '"'
14+
buildConfigField "String", "APP_BUILD_TIME", '"' + (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.ROOT).format(new Date())) + '"'
1415
}
1516

1617
compileSdkVersion 29

FtcRobotController/src/main/AndroidManifest.xml

+17-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
xmlns:tools="http://schemas.android.com/tools"
44
package="com.qualcomm.ftcrobotcontroller"
5-
android:versionCode="40"
6-
android:versionName="6.2">
5+
android:versionCode="42"
6+
android:versionName="7.0">
77

88
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
99

@@ -61,6 +61,21 @@
6161
android:name="com.qualcomm.ftccommon.FtcRobotControllerService"
6262
android:enabled="true" />
6363

64+
65+
<!-- Assistant that autostarts the robot controller on android boot (if it's supposed to) -->
66+
<receiver
67+
android:enabled="true"
68+
android:exported="true"
69+
android:name="org.firstinspires.ftc.ftccommon.internal.RunOnBoot"
70+
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
71+
72+
<intent-filter>
73+
<category android:name="android.intent.category.DEFAULT" />
74+
<action android:name="android.intent.action.BOOT_COMPLETED" />
75+
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
76+
</intent-filter>
77+
</receiver>
78+
6479
</application>
6580

6681
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
package org.firstinspires.ftc.robotcontroller.external.samples;
2+
3+
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
4+
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
5+
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
6+
import com.qualcomm.robotcore.hardware.Gamepad;
7+
import com.qualcomm.robotcore.util.ElapsedTime;
8+
9+
/**
10+
* This sample illustrates using the rumble feature of many gamepads.
11+
*
12+
* Note: Some gamepads "rumble" better than others.
13+
* The Xbox & PS4 have a left (rumble1) and right (rumble2) rumble motor.
14+
* These two gamepads have two distinct rumble modes: Large on the left, and small on the right
15+
* The ETpark gamepad may only respond to rumble1, and may only run at full power.
16+
* The Logitech F310 gamepad does not have *any* rumble ability.
17+
*
18+
* Moral: You should use this sample to experiment with your specific gamepads to explore their rumble features.
19+
*
20+
* The rumble motors are accessed through the standard gamepad1 and gamepad2 objects.
21+
* Several new methods were added to the Gamepad class in FTC SDK Rev 7
22+
* The key methods are as follows:
23+
*
24+
* .rumble(double rumble1, double rumble2, int durationMs)
25+
* This method sets the rumble power of both motors for a specific time duration.
26+
* Both rumble arguments are motor-power levels in the 0.0 to 1.0 range.
27+
* durationMs is the desired length of the rumble action in milliseconds.
28+
* This method returns immediately.
29+
* Note:
30+
* Use a durationMs of Gamepad.RUMBLE_DURATION_CONTINUOUS to provide a continuous rumble
31+
* Use a power of 0, or duration of 0 to stop a rumble.
32+
*
33+
* .rumbleBlips(int count) allows an easy way to signal the driver with a series of rumble blips.
34+
* Just specify how many blips you want.
35+
* This method returns immediately.
36+
*
37+
* .runRumbleEffect(customRumbleEffect) allows you to run a custom rumble sequence that you have
38+
* built using the Gamepad.RumbleEffect.Builder()
39+
* A "custom effect" is a sequence of steps, where each step can rumble any of the
40+
* rumble motors for a specific period at a specific power level.
41+
* The Custom Effect will play as the (un-blocked) OpMode continues to run
42+
*
43+
* .isRumbling() returns true if there is a rumble effect in progress.
44+
* Use this call to prevent stepping on a current rumble.
45+
*
46+
* .stopRumble() Stop any ongoing rumble or custom rumble effect.
47+
*
48+
* .rumble(int durationMs) Full power rumble for fixed duration.
49+
*
50+
* Note: Whenever a new Rumble command is issued, any currently executing rumble action will
51+
* be truncated, and the new action started immediately. Take these precautions:
52+
* 1) Do Not SPAM the rumble motors by issuing rapid fire commands
53+
* 2) Multiple sources for rumble commands must coordinate to avoid tromping on each other.
54+
*
55+
* This can be achieved several possible ways:
56+
* 1) Only having one source for rumble actions
57+
* 2) Issuing rumble commands on transitions, rather than states.
58+
* e.g. The moment a touch sensor is pressed, rather than the entire time it is being pressed.
59+
* 3) Scheduling rumble commands based on timed events. e.g. 10 seconds prior to endgame
60+
* 4) Rumble on non-overlapping mechanical actions. e.g. arm fully-extended or fully-retracted.
61+
* 5) Use isRumbling() to hold off on a new rumble if one is already in progress.
62+
*
63+
* The examples shown here are representstive of how to invoke a gamepad rumble.
64+
* It is assumed that these will be modified to suit the specific robot and team strategy needs.
65+
*
66+
* ######## Read the telemetry display on the Driver Station Screen for instructions. ######
67+
*
68+
* Ex 1) This example shows a) how to create a custom rumble effect, and then b) how to trigger it based
69+
* on game time. One use for this might be to alert the driver that half-time or End-game is approaching.
70+
*
71+
* Ex 2) This example shows tying the rumble power to a changing sensor value.
72+
* In this case it is the Gamepad trigger, but it could be any sensor output scaled to the 0-1 range.
73+
* Since it takes over the rumble motors, it is only performed when the Left Bumper is pressed.
74+
* Note that this approach MUST include a way to turn OFF the rumble when the button is released.
75+
*
76+
* Ex 3) This example shows a simple way to trigger a 3-blip sequence. In this case it is
77+
* triggered by the gamepad A (Cross) button, but it could be any sensor, like a touch or light sensor.
78+
* Note that this code ensures that it only rumbles once when the input goes true.
79+
*
80+
* Ex 4) This example shows how to trigger a single rumble when an input value gets over a certain value.
81+
* In this case it is reading the Right Trigger, but it could be any variable sensor, like a
82+
* range sensor, or position sensor. The code needs to ensure that it is only triggered once, so
83+
* it waits till the sensor drops back below the threshold before it can trigger again.
84+
*
85+
* Use Android Studio to Copy this Class, and Paste it into your team's code folder with a new name.
86+
* Remove or comment out the @Disabled line to add this OpMode to the Driver Station OpMode list.
87+
*/
88+
89+
@Disabled
90+
@TeleOp(name="Concept: Gamepad Rumble", group ="Concept")
91+
public class ConceptGamepadRumble extends LinearOpMode
92+
{
93+
boolean lastA = false; // Use to track the prior button state.
94+
boolean lastLB = false; // Use to track the prior button state.
95+
boolean highLevel = false; // used to prevent multiple level-based rumbles.
96+
boolean secondHalf = false; // Use to prevent multiple half-time warning rumbles.
97+
98+
Gamepad.RumbleEffect customRumbleEffect; // Use to build a custom rumble sequence.
99+
ElapsedTime runtime = new ElapsedTime(); // Use to determine when end game is starting.
100+
101+
final double HALF_TIME = 60.0; // Wait this many seconds before rumble-alert for half-time.
102+
final double TRIGGER_THRESHOLD = 0.75; // Squeeze more than 3/4 to get rumble.
103+
104+
@Override
105+
public void runOpMode()
106+
{
107+
// Example 1. a) start by creating a three-pulse rumble sequence: right, LEFT, LEFT
108+
customRumbleEffect = new Gamepad.RumbleEffect.Builder()
109+
.addStep(0.0, 1.0, 500) // Rumble right motor 100% for 500 mSec
110+
.addStep(0.0, 0.0, 300) // Pause for 300 mSec
111+
.addStep(1.0, 0.0, 250) // Rumble left motor 100% for 250 mSec
112+
.addStep(0.0, 0.0, 250) // Pause for 250 mSec
113+
.addStep(1.0, 0.0, 250) // Rumble left motor 100% for 250 mSec
114+
.build();
115+
116+
telemetry.addData(">", "Press Start");
117+
telemetry.update();
118+
119+
waitForStart();
120+
runtime.reset(); // Start game timer.
121+
122+
// Loop while monitoring buttons for rumble triggers
123+
while (opModeIsActive())
124+
{
125+
// Read and save the current gamepad button states.
126+
boolean currentA = gamepad1.a ;
127+
boolean currentLB = gamepad1.left_bumper ;
128+
129+
// Display the current Rumble status. Just for interest.
130+
telemetry.addData(">", "Are we RUMBLING? %s\n", gamepad1.isRumbling() ? "YES" : "no" );
131+
132+
// ----------------------------------------------------------------------------------------
133+
// Example 1. b) Watch the runtime timer, and run the custom rumble when we hit half-time.
134+
// Make sure we only signal once by setting "secondHalf" flag to prevent further rumbles.
135+
// ----------------------------------------------------------------------------------------
136+
if ((runtime.seconds() > HALF_TIME) && !secondHalf) {
137+
gamepad1.runRumbleEffect(customRumbleEffect);
138+
secondHalf =true;
139+
}
140+
141+
// Display the time remaining while we are still counting down.
142+
if (!secondHalf) {
143+
telemetry.addData(">", "Halftime Alert Countdown: %3.0f Sec \n", (HALF_TIME - runtime.seconds()) );
144+
}
145+
146+
147+
// ----------------------------------------------------------------------------------------
148+
// Example 2. If Left Bumper is being pressed, power the rumble motors based on the two trigger depressions.
149+
// This is useful to see how the rumble feels at various power levels.
150+
// ----------------------------------------------------------------------------------------
151+
if (currentLB) {
152+
// Left Bumper is being pressed, so send left and right "trigger" values to left and right rumble motors.
153+
gamepad1.rumble(gamepad1.left_trigger, gamepad1.right_trigger, Gamepad.RUMBLE_DURATION_CONTINUOUS);
154+
155+
// Show what is being sent to rumbles
156+
telemetry.addData(">", "Squeeze triggers to control rumbles");
157+
telemetry.addData("> : Rumble", "Left: %.0f%% Right: %.0f%%", gamepad1.left_trigger * 100, gamepad1.right_trigger * 100);
158+
} else {
159+
// Make sure rumble is turned off when Left Bumper is released (only one time each press)
160+
if (lastLB) {
161+
gamepad1.stopRumble();
162+
}
163+
164+
// Prompt for manual rumble action
165+
telemetry.addData(">", "Hold Left-Bumper to test Manual Rumble");
166+
telemetry.addData(">", "Press A (Cross) for three blips");
167+
telemetry.addData(">", "Squeeze right trigger slowly for 1 blip");
168+
}
169+
lastLB = currentLB; // remember the current button state for next time around the loop
170+
171+
172+
// ----------------------------------------------------------------------------------------
173+
// Example 3. Blip 3 times at the moment that A (Cross) is pressed. (look for pressed transition)
174+
// BUT !!! Skip it altogether if the Gamepad is already rumbling.
175+
// ----------------------------------------------------------------------------------------
176+
if (currentA && !lastA) {
177+
if (!gamepad1.isRumbling()) // Check for possible overlap of rumbles.
178+
gamepad1.rumbleBlips(3);
179+
}
180+
lastA = currentA; // remember the current button state for next time around the loop
181+
182+
183+
// ----------------------------------------------------------------------------------------
184+
// Example 4. Rumble once when gamepad right trigger goes above the THRESHOLD.
185+
// ----------------------------------------------------------------------------------------
186+
if (gamepad1.right_trigger > TRIGGER_THRESHOLD) {
187+
if (!highLevel) {
188+
gamepad1.rumble(0.9, 0, 200); // 200 mSec burst on left motor.
189+
highLevel = true; // Hold off any more triggers
190+
}
191+
} else {
192+
highLevel = false; // We can trigger again now.
193+
}
194+
195+
// Send the telemetry data to the Driver Station, and then pause to pace the program.
196+
telemetry.update();
197+
sleep(10);
198+
}
199+
}
200+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package org.firstinspires.ftc.robotcontroller.external.samples;
2+
3+
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
4+
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
5+
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
6+
7+
import org.firstinspires.ftc.robotcore.external.Telemetry;
8+
9+
/**
10+
* This sample illustrates using the touchpad feature found on some gamepads.
11+
*
12+
* The Sony PS4 gamepad can detect two distinct touches on the central touchpad.
13+
* Other gamepads with different touchpads may provide mixed results.
14+
*
15+
* The touchpads are accessed through the standard gamepad1 and gamepad2 objects.
16+
* Several new members were added to the Gamepad class in FTC SDK Rev 7
17+
*
18+
* .touchpad_finger_1 returns true if at least one finger is detected.
19+
* .touchpad_finger_1_x finger 1 X coordinate. Valid if touchpad_finger_1 is true
20+
* .touchpad_finger_1_y finger 1 Y coordinate. Valid if touchpad_finger_1 is true
21+
*
22+
* .touchpad_finger_2 returns true if a second finger is detected
23+
* .touchpad_finger_2_x finger 2 X coordinate. Valid if touchpad_finger_2 is true
24+
* .touchpad_finger_2_y finger 2 Y coordinate. Valid if touchpad_finger_2 is true
25+
*
26+
* Finger touches are reported with an X and Y coordinate in following coordinate system.
27+
*
28+
* 1) X is the Horizontal axis, and Y is the vertical axis
29+
* 2) The 0,0 origin is at the center of the touchpad.
30+
* 3) 1.0, 1.0 is at the top right corner of the touchpad.
31+
* 4) -1.0,-1.0 is at the bottom left corner of the touchpad.
32+
*
33+
* Use Android Studio to Copy this Class, and Paste it into your team's code folder with a new name.
34+
* Remove or comment out the @Disabled line to add this OpMode to the Driver Station OpMode list.
35+
*/
36+
37+
@Disabled
38+
@TeleOp(name="Concept: Gamepad Touchpad", group ="Concept")
39+
public class ConceptGamepadTouchpad extends LinearOpMode
40+
{
41+
@Override
42+
public void runOpMode()
43+
{
44+
telemetry.setDisplayFormat(Telemetry.DisplayFormat.MONOSPACE);
45+
46+
telemetry.addData(">", "Press Start");
47+
telemetry.update();
48+
49+
waitForStart();
50+
51+
while (opModeIsActive())
52+
{
53+
boolean finger = false;
54+
55+
// Display finger 1 x & y position if finger detected
56+
if(gamepad1.touchpad_finger_1)
57+
{
58+
finger = true;
59+
telemetry.addLine(String.format("Finger 1: x=%5.2f y=%5.2f\n", gamepad1.touchpad_finger_1_x, gamepad1.touchpad_finger_1_y));
60+
}
61+
62+
// Display finger 2 x & y position if finger detected
63+
if(gamepad1.touchpad_finger_2)
64+
{
65+
finger = true;
66+
telemetry.addLine(String.format("Finger 2: x=%5.2f y=%5.2f\n", gamepad1.touchpad_finger_2_x, gamepad1.touchpad_finger_2_y));
67+
}
68+
69+
if(!finger)
70+
{
71+
telemetry.addLine("No fingers");
72+
}
73+
74+
telemetry.update();
75+
sleep(10);
76+
}
77+
}
78+
}

FtcRobotController/src/main/java/org/firstinspires/ftc/robotcontroller/external/samples/ConceptTensorFlowObjectDetection.java

+23-9
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141

4242
/**
4343
* This 2020-2021 OpMode illustrates the basics of using the TensorFlow Object Detection API to
44-
* determine the position of the Ultimate Goal game elements.
44+
* determine the position of the Freight Frenzy game elements.
4545
*
4646
* Use Android Studio to Copy this Class, and Paste it into your team's code folder with a new name.
4747
* Remove or comment out the @Disabled line to add this opmode to the Driver Station OpMode list.
@@ -52,9 +52,24 @@
5252
@TeleOp(name = "Concept: TensorFlow Object Detection", group = "Concept")
5353
@Disabled
5454
public class ConceptTensorFlowObjectDetection extends LinearOpMode {
55-
private static final String TFOD_MODEL_ASSET = "UltimateGoal.tflite";
56-
private static final String LABEL_FIRST_ELEMENT = "Quad";
57-
private static final String LABEL_SECOND_ELEMENT = "Single";
55+
/* Note: This sample uses the all-objects Tensor Flow model (FreightFrenzy_BCDM.tflite), which contains
56+
* the following 4 detectable objects
57+
* 0: Ball,
58+
* 1: Cube,
59+
* 2: Duck,
60+
* 3: Marker (duck location tape marker)
61+
*
62+
* Two additional model assets are available which only contain a subset of the objects:
63+
* FreightFrenzy_BC.tflite 0: Ball, 1: Cube
64+
* FreightFrenzy_DM.tflite 0: Duck, 1: Marker
65+
*/
66+
private static final String TFOD_MODEL_ASSET = "FreightFrenzy_BCDM.tflite";
67+
private static final String[] LABELS = {
68+
"Ball",
69+
"Cube",
70+
"Duck",
71+
"Marker"
72+
};
5873

5974
/*
6075
* IMPORTANT: You need to obtain your own license key to use Vuforia. The string below with which
@@ -128,16 +143,13 @@ public void runOpMode() {
128143
recognition.getLeft(), recognition.getTop());
129144
telemetry.addData(String.format(" right,bottom (%d)", i), "%.03f , %.03f",
130145
recognition.getRight(), recognition.getBottom());
146+
i++;
131147
}
132148
telemetry.update();
133149
}
134150
}
135151
}
136152
}
137-
138-
if (tfod != null) {
139-
tfod.shutdown();
140-
}
141153
}
142154

143155
/**
@@ -166,7 +178,9 @@ private void initTfod() {
166178
"tfodMonitorViewId", "id", hardwareMap.appContext.getPackageName());
167179
TFObjectDetector.Parameters tfodParameters = new TFObjectDetector.Parameters(tfodMonitorViewId);
168180
tfodParameters.minResultConfidence = 0.8f;
181+
tfodParameters.isModelTensorFlow2 = true;
182+
tfodParameters.inputSize = 320;
169183
tfod = ClassFactory.getInstance().createTFObjectDetector(tfodParameters, vuforia);
170-
tfod.loadModelFromAsset(TFOD_MODEL_ASSET, LABEL_FIRST_ELEMENT, LABEL_SECOND_ELEMENT);
184+
tfod.loadModelFromAsset(TFOD_MODEL_ASSET, LABELS);
171185
}
172186
}

0 commit comments

Comments
 (0)