Skip to content
CrocoDocs
Starter GuideProgrammingEngineeringDesignPortfolio
Documentation

Introduction

IntroductionBIOBUZZ game overview

Getting started

Getting startedBlocksOnBot JavaAndroid StudioYour first OpModeJava basicsMotors and servosNonblocking codeDebugging robot code

Control systems

Control systemsJoystick mappingField-centric mecanum drivePID controlFeedforwardFlywheel velocity controlSystem identificationMotion profilingKalman filterLow-pass filter

Autonomous

AutonomousTimed and encoder movementOdometryLocalization troubleshootingMotion planningReliable autonomous sequencesPure PursuitSensor fusionAuto to TeleOp handoff

Season topics

Season topicsProjectile mathematicsTurret aimingShooting on the move

Code practices

Code practicesNaming conventionsCode organizationLoop timing and bulk readsFormattingComments and documentationTeam collaboration

Libraries

LibrariesNextFTCFTCLibSolversLibPedro PathingRoad RunnerFTC DashboardMercurial v2Mercurial v1PanelsSloth

Community software

Community softwareBlaze FTCOpenLoopHive Vision

Sensors and vision

Vision overviewVision basicsLimelight 3A
Starter Guide
Engineering
Design
Portfolio
Appearance

Debugging robot code

Separate build, configuration, runtime, and behavior failures with evidence

First find where the problem starts: building the code, installing it, setting up hardware, or moving the . Check that stage before changing anything else. A controller gain will not fix a missing import, and a successful build will not catch an that counts in the wrong direction.

Build errors

Read the first relevant compiler error, its file, and its line number. Later errors may follow from that one mistake. Check the class name, braces, imports, and the installed API version. A copied tutorial may target a different library major version or use pseudocode.

In Android Studio, jump to a method's definition and inspect its parameter types, units, return value, and lifecycle. Compare it with the official sample from the SDK version installed in the project. The standard SDK 12 project uses 8 language compatibility; code that compiles in a desktop Java 17 project may rely on APIs unavailable on the robot's Android version.

Gradle and dependency failures

ErrorCheck before changing code
Unknown host or a dependency download failsSync on an internet connection first. Robot Wi-Fi usually does not provide internet access. Check the repository and exact artifact version next.
JVM/Gradle incompatibility after an IDE updateCheck the project's Gradle wrapper and Android plugin requirements, then the Gradle JDK selected in Android Studio. ./gradlew --version shows the command-line runtime, which may differ.
Unable to delete directory or AccessDeniedException in build outputClose processes holding the files. Keep the working checkout outside cloud-sync folders such as OneDrive; use Git to share source.
ClassNotFoundException, NoSuchMethodError, or IncompatibleClassChangeErrorCompare the dependency graph with the installed SDK and library major versions. Perform a full install after a dependency change.

The JDK that runs Gradle, the Java source language level, and the APIs available on Android are separate choices. Upgrading all three until the error changes can introduce another incompatibility. Start from the supported FTC project and the library's matching installation instructions.

For a dependency conflict, run this read-only report from the project root, then inspect which version each library actually resolves to:

./gradlew :TeamCode:dependencies --configuration debugRuntimeClasspath

Installation

Add a visible build label to telemetry, such as telemetry.addLine("Practice build 3"), and redeploy. If it does not change, verify the selected device, successful install, and correct . Android Studio's standard application module is TeamCode. With Sloth, clear remote hot-reloaded classes before a normal full install as described in the Sloth guide.

Install the app on the , then operate it with the app on the Driver Hub. A successful install on the wrong device does not update the robot. An OpMode also needs its annotation, the expected package, a unique displayed name, and no @Disabled annotation. Plain subsystem/helper classes do not need @TeleOp.

Robot Controller startup crashes

A blue hub light is a symptom, not a diagnosis. Capture the Robot Controller log around startup and find the first meaningful exception. Class scanning can encounter a dependency failure before any OpMode starts. A desktop dependency that requires Swing, for example, does not become Android-compatible because it is only used by a helper class.

Compare the failing project with a known working full install, then narrow the changed dependencies or classes. Preserve and OnBot Java work before following any recovery procedure that removes files or app data. A reported fix for one stale generated class is not a reason to erase every team's programs. Use the hardware manufacturer's recovery process if the hub itself remains inaccessible.

Hardware configuration

A hardwareMap error often means the requested name or device type does not match the active configuration. Compare capitalization and the configured port. Confirm a is not being requested as a , and that the robot is using the configuration you edited.

Do not rename several devices and rewrite the controller at once. Test one mapped device with telemetry, then add its output command at low power.

Runtime failures

An exception stack trace identifies the failing method and call path. Look for your TeamCode file and line, then inspect its inputs. Common causes include a null detection, an empty list indexed at zero, an invalid format string, and a lifecycle method called before hardware exists.

For example, %d formats an integer while %.1f formats a floating-point value. A method returning int does not become a floating-point argument just because telemetry displays it. Check the declared return type instead of guessing.

Incorrect motion

Log the smallest useful set of values: requested target, raw measurement, converted measurement, error, output, state, and elapsed time. Include units. Test the direction of a small positive output independently from the measurement conversion.

For an arm moving away from its target, stop and check output sign, sign, encoder zero, and units before tuning gains. For an miss, compare the real position with localization telemetry. A correct encoder target can coexist with wheel slip and a wrong field endpoint.

Use localization troubleshooting when turns corrupt a pose, field-centric drive when stick directions change with heading, and loop timing when measurements or controls lag.

Live tuning does not change behaviour

Print the configurable field and the value the controller actually uses. A controller constructed with a copied gain may never reread the live field. Check supported public/static configuration fields, then reduce to one dashboard with the documented setup for the installed versions. Telemetry arriving in the browser does not prove that configuration writes reach the same loaded class. Save successful tuning values back into source.

Repeatable tests

Record the code revision, starting pose, battery condition, load, and result. Change one suspected cause, repeat the same test, and compare. Keep failed trials: removing them produces a misleading reliability estimate. After a repair, repeat the original failing case and a nearby normal case.

If the fault remains unclear, reduce to a small OpMode with one device and enough telemetry to reproduce it. Keep private network details out of public logs. For mechanical failures and on-field testing, use Testing and reliability.

Testing without a robot

Keep geometry, unit conversions, and sequence decisions separate from hardware calls. Test those pure Java helpers in a normal Java project with representative inputs and explicit expected outcomes. The arrival gate can exercise a or stale measurement without a Control Hub; the turret helper can reject an unreachable angle without a servo.

Compile robot-facing examples against the SDK version your team uses. A desktop compile does not exercise Android's class loading, device discovery, motor direction, or physical motion. Use a for the hardware and APIs it supports, then repeat the affected behaviour on the robot. Creating an OpMode with new in a desktop main() method does not supply its hardware map or SDK lifecycle.

Sources

  • Official FTC SDK source and samples
  • FTC programming resources
  • Learn Java for FTC — API lookup and debugging exercises.
  • Android Developers: JDKs, Gradle, and source compatibility
  • Gradle: dependency reports
  • REV: Control Hub troubleshooting

Nonblocking code

Keep the robot loop responsive with button edges, timestamps, and state

Control systems

Learn how commands, sensors, and feedback affect robot motion

On this page

Build errorsGradle and dependency failuresInstallationRobot Controller startup crashesHardware configurationRuntime failuresIncorrect motionLive tuning does not change behaviourRepeatable testsTesting without a robotSources