Field View
It provides a dynamic and interactive visualization of the game field, allowing teams to monitor their robot's position, orientation, and interactions with game elements in real-time. This feature is particularly useful for debugging autonomous flows, tracking robot movements.
It works live a canvas, so it can be used for any drawing application.
Supported Objects
- Line
- Circle
- Rectangle
More will be added soon
Customization
You can change the orientation and show a coordinates grid inside the settings menu
.
There are also methods on the Canvas
object to change the orientation programatically: setOffsets
.

Gotchas
- Objects are drawn in the order they are sent to the
debug
function, and their layering (z-index) is automatically managed by the system. - The input order is flexible, you can provide Drawable objects and text lines in any order within the debug function.
- Every Drawable object requires a
look
to define its visual appearance. The look specifies styling attributes such as fillColor, outlineColor, outlineWidth.
Example OpMode File: TestOpMode.kt
Below is an example of how field telemetry can be implemented in an OpMode:
package org.firstinspires.ftc.teamcode.examples.field
import com.bylazar.ftcontrol.panels.Panels
import com.bylazar.ftcontrol.panels.json.CanvasRotation
import com.bylazar.ftcontrol.panels.json.Circle
import com.bylazar.ftcontrol.panels.json.Line
import com.bylazar.ftcontrol.panels.json.Look
import com.bylazar.ftcontrol.panels.json.Point
import com.bylazar.ftcontrol.panels.json.Rectangle
import com.qualcomm.robotcore.eventloop.opmode.OpMode
import com.qualcomm.robotcore.eventloop.opmode.TeleOp
import kotlin.random.Random
@TeleOp(name = "Field Test OpMode")
class TestOpMode : OpMode() {
var panelsTelemetry = Panels.getTelemetry()
override fun init() {
panelsTelemetry.setOffsets(24.0, 24.0, CanvasRotation.DEG_0) //field offsets in inches
panelsTelemetry.debug("Init was ran!")
panelsTelemetry.update(telemetry)
}
override fun loop() {
panelsTelemetry.debug("Loop ${System.currentTimeMillis()} ran!")
panelsTelemetry.debug(
Line(
Point(0.0, 0.0),
Point(0.0, Random.nextDouble(0.0, 10.0)),
).withLook(
Look(
outlineColor = "red",
outlineWidth = 1.0,
fillColor = "",
opacity = 1.0
)
),
Circle(
Point(20.0, 20.0),
Random.nextDouble(0.0, 10.0),
).withLook(
Look(
outlineColor = "blue",
outlineWidth = 1.0,
fillColor = "yellow",
opacity = 1.0
)
),
Rectangle(
Point(40.0, 40.0),
Random.nextDouble(0.0, 10.0),
Random.nextDouble(0.0, 10.0),
).withLook(
Look(
outlineColor = "green",
outlineWidth = 1.0,
fillColor = "",
opacity = 1.0
)
)
)
panelsTelemetry.update(telemetry)
}
}
Example Drawer File: Drawer.kt
Below is an example of how field telemetry can be implemented in an utility without the opMode loop:
package org.firstinspires.ftc.teamcode.examples.field
import com.bylazar.ftcontrol.panels.Panels
import com.bylazar.ftcontrol.panels.json.Canvas
import com.bylazar.ftcontrol.panels.json.CanvasRotation
import com.bylazar.ftcontrol.panels.json.Circle
import com.bylazar.ftcontrol.panels.json.Look
import com.bylazar.ftcontrol.panels.json.Point
class Drawer {
fun draw() {
val canvas = Canvas().withOffsetX(0.0).withOffsetY(0.0).withRotation(CanvasRotation.DEG_0)
canvas.add(
Circle(
center = Point(0.0, 0.0),
radius = 10.0,
).withLook(
Look(
outlineColor = "red",
outlineWidth = 1.0,
fillColor = "",
opacity = 1.0
)
)
)
Panels.getTelemetry().sendCanvas(canvas)
}
}
A library by Lazar from 19234 ByteForce.