What is Telemetry?
Telemetry lets you send data from your robot to the Driver Station for real-time monitoring and debugging. It is essential for understanding what your robot is doing during a match and for troubleshooting issues.
Telemetry can display sensor values, motor powers, program states, and more.
Why Use Telemetry? Telemetry helps you:
Debug your code by displaying variable values.
Monitor robot status in real time.
Communicate important information to drivers.
Track sensor and motor data during matches.
Basic Telemetry Example
Here is an example showing how to use telemetry in a LinearOpMode. This example displays motor power and a custom message on the Driver Station.
Telemetry in LinearOpMode
@ TeleOp ( name = "TelemetryExample" )
public class TelemetryExample extends LinearOpMode {
private DcMotor leftDrive, rightDrive;
@ Override
public void runOpMode () {
leftDrive = hardwareMap. get (DcMotor.class, "left_drive" );
rightDrive = hardwareMap. get (DcMotor.class, "right_drive" );
waitForStart ();
while ( opModeIsActive ()) {
double leftPower = - gamepad1.left_stick_y;
double rightPower = - gamepad1.right_stick_y;
leftDrive. setPower (leftPower);
rightDrive. setPower (rightPower);
telemetry. addData ( "Left Power" , leftPower);
telemetry. addData ( "Right Power" , rightPower);
telemetry. addData ( "Status" , "Running" );
telemetry. update ();
}
}
}
Advanced Telemetry Techniques
You can group telemetry data, use telemetry.log() for persistent messages, and display sensor values.
Telemetry can also be used in Iterative OpModes and for debugging autonomous routines.
Telemetry with Sensors
@ TeleOp ( name = "SensorTelemetry" )
public class SensorTelemetry extends LinearOpMode {
private DistanceSensor distanceSensor;
@ Override
public void runOpMode () {
distanceSensor = hardwareMap. get (DistanceSensor.class, "sensor_distance" );
waitForStart ();
while ( opModeIsActive ()) {
double distance = distanceSensor. getDistance (DistanceUnit.CM);
telemetry. addData ( "Distance (cm)" , distance);
telemetry. update ();
}
}
}
Best Practices for Telemetry Tips for effective telemetry:
Call telemetry.update() once per loop.
Use clear, descriptive labels for data.
Limit the amount of data to avoid clutter.
Use telemetry for debugging and driver feedback.
Practice: Telemetry Logging Try these to reinforce your understanding:
Add telemetry to your existing OpModes.
Display sensor values and custom messages.
Experiment with telemetry.log() for persistent messages.
Show Answers Add telemetry to your existing OpModes
// Add this to your existing OpMode's main loop:
while (opModeIsActive()) {
// Your existing robot control code here
double leftPower = -gamepad1.left_stick_y;
double rightPower = -gamepad1.right_stick_y;
leftDrive.setPower(leftPower);
rightDrive.setPower(rightPower);
// Add telemetry for debugging and monitoring
telemetry.addData("Left Drive Power", leftPower);
telemetry.addData("Right Drive Power", rightPower);
telemetry.addData("Status", "TeleOp Running");
telemetry.addData("Gamepad Connected", gamepad1.atRest());
telemetry.update();
}
Display sensor values and custom messages
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.hardware.DcMotor;
import com.qualcomm.robotcore.hardware.ColorSensor;
import com.qualcomm.robotcore.hardware.DistanceSensor;
import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit;
@TeleOp(name = "SensorTelemetry")
public class SensorTelemetry extends LinearOpMode {
private DcMotor driveMotor;
private ColorSensor colorSensor;
private DistanceSensor distanceSensor;
@Override
public void runOpMode() {
// Initialize hardware
driveMotor = hardwareMap.get(DcMotor.class, "drive_motor");
colorSensor = hardwareMap.get(ColorSensor.class, "color_sensor");
distanceSensor = hardwareMap.get(DistanceSensor.class, "distance_sensor");
// Show initialization status
telemetry.addData("Status", "Sensors Initialized");
telemetry.update();
waitForStart();
while (opModeIsActive()) {
// Read sensor values
int red = colorSensor.red();
int green = colorSensor.green();
int blue = colorSensor.blue();
double distance = distanceSensor.getDistance(DistanceUnit.CM);
// Display sensor data
telemetry.addData("Color Sensor", "R:%d G:%d B:%d", red, green, blue);
telemetry.addData("Distance (cm)", "%.1f", distance);
telemetry.addData("Motor Power", driveMotor.getPower());
// Add custom status messages
if (distance < 10) {
telemetry.addData("Warning", "Object too close!");
}
telemetry.update();
}
}
}
Experiment with telemetry.log() for persistent messages
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.hardware.DcMotor;
@TeleOp(name = "LoggingExample")
public class LoggingExample extends LinearOpMode {
private DcMotor driveMotor;
private int loopCount = 0;
@Override
public void runOpMode() {
driveMotor = hardwareMap.get(DcMotor.class, "drive_motor");
// Log initialization - this stays in the log
telemetry.log().add("OpMode initialized successfully");
telemetry.update();
waitForStart();
// Log start of match
telemetry.log().add("Match started!");
telemetry.update();
while (opModeIsActive()) {
loopCount++;
double power = -gamepad1.left_stick_y;
driveMotor.setPower(power);
// Regular telemetry (updates each loop)
telemetry.addData("Loop Count", loopCount);
telemetry.addData("Motor Power", power);
// Log important events (persistent)
if (Math.abs(power) > 0.8) {
telemetry.log().add("High power detected: " + power);
}
if (loopCount % 100 == 0) {
telemetry.log().add("Completed " + loopCount + " loops");
}
telemetry.update();
}
// Log end of match
telemetry.log().add("Match ended. Total loops: " + loopCount);
telemetry.update();
}
}