Java basics
Values, scope, conditions, loops, methods, and classes in robot code
code names values, makes decisions, and calls methods. Before adding a command framework or a controller, practice those operations in the telemetry loop from Your first OpMode. The examples on this page are small fragments with their placement stated.
Values and types
A variable has a type, a name, and a value. Types determine which operations are allowed.
// Inside runOpMode():
int capturedPieces = 0;
double targetInches = 12.5;
boolean atLimit = false;
String mechanismName = "intake";int stores whole numbers. double stores floating-point values. boolean is true or false. String stores text. Use units in measurement names so a value in ticks is not mistaken for inches. Java does not check physical units for you.
= assigns a value; == compares primitive values. Compare String contents with .equals(), such as "intake".equals(mechanismName), rather than ==, which compares object references.
telemetry.addData("Integer division", 1 / 2); // 0
telemetry.addData("Decimal division", 1.0 / 2.0); // 0.5When both operands are integers, Java performs integer division. Converting the result afterward cannot recover the discarded fraction. This matters in encoder and gear-ratio calculations.
Division playground
Near the top of this example, double power = 1 / 2 assigns 0.0: Java divides the two integers first, then stores the result as a double. Press Play. The stays still because its requested power is zero.
Change 1 / 2 to 1.0 / 2 and press Play again. The result is now 0.5, and the robot drives for one second. Press Reset between trials. Changing the calculation back to 1 / 2 makes it stay still again; the variable's type alone does not preserve the fraction.
Edit the example, then press Play. Reloading this page or changing theme restores the example.
Scope
A local exists inside its method or block. A field belongs to an object and can keep state between method calls.
// Inside the OpMode class, outside every method:
private boolean previousA = false;
// Inside the active loop:
boolean currentA = gamepad1.a;
boolean justPressed = currentA && !previousA;
previousA = currentA;previousA must survive the next loop. Declaring it as false inside the loop would reset it on every pass. currentA can be local because only the current pass needs it.
private limits access to the class. final prevents assigning a different value or object to that variable after initialisation; you can still call methods on a final . static shares a field across all instances of the class, so ordinary hardware fields should not be static.
Conditions
// Inside an active loop, after defining these example values:
boolean sensorValid = true;
int capturedPieces = 3;
if (sensorValid && capturedPieces < 4) {
telemetry.addLine("Collection permitted by this example's count check");
} else {
telemetry.addLine("Stop collection or check the sensor");
}&& means both conditions must hold; || means at least one must hold; ! negates a boolean. Both && and || short-circuit, so the right operand is evaluated only when needed. A counter is useful evidence, but it does not prove the robot's actual game-piece CONTROL is legal.
For non-null objects, a guard such as target != null && target.isVisible() avoids calling a method through a null reference. Put the null check first.
Loops
Use while when repetition depends on a condition and for for a bounded count. This fragment belongs inside a LinearOpMode after START:
while (opModeIsActive()) {
telemetry.addData("Stick", gamepad1.left_stick_y);
telemetry.update();
idle();
}A separate inner loop can prevent the outer loop from reading buttons or updating another . Replace a long wait with a timestamp and state when other work must continue. See Nonblocking code.
Methods and classes
A method names a calculation or operation. Parameters supply its inputs; return supplies its result. Put this helper at class scope, outside runOpMode():
private double ticksToInches(int ticks, double countsPerInch) {
if (!Double.isFinite(countsPerInch) || countsPerInch <= 0.0) {
throw new IllegalArgumentException("Positive finite encoder scale required");
}
return ticks / countsPerInch;
}Call it inside the loop with a measured scale. ticksToInches(125, 50.0) returns 2.5; the helper does not reset an encoder or move a motor.
A class groups related values and methods. A constructor sets up a new object. An OpMode is one example of an object; a mechanism class could hold a motor and offer a method for setting its target.
Give each piece of hardware a clear owner before adding inheritance or a command scheduler. The code organization guide explains when a separate class helps.
Practice
Predict 3 / 2, 3 / 2.0, and 3.0 / 2 before displaying them. Then add a field that counts button presses, using justPressed rather than the held button. Hold A for a second: the counter should increase once. If it increases every loop, inspect the state update and variable scope.