Overview

CDALib is a structured way to build FTC OpModes out of reusable parts instead of one giant class.

CDALib is a FIRST Tech Challenge (FTC) robot-code library that gives your team a consistent shape for every OpMode. Rather than writing a monolithic OpMode that pokes hardware directly and hand-rolls its own loop, you assemble a robot from small, testable pieces — subsystems, devices, controllers, bindings, tasks, and modules — and let CDALib run their lifecycles for you.

It is built on top of PedroPathing 3.0 for autonomous path following and PhotonFTC for lower loop times. Lynx hub bulk caching is handled automatically: each loop performs a single bulk read of every sensor and encoder, so you get low, predictable cycle times without wiring that up yourself. Both PedroPathing and PhotonFTC arrive transitively when you depend on CDALib — see Installation.

Built on: FTC SDK 12.0.0 · PedroPathing 3.0.1 · PhotonFTC (optional, via @Photon) · Panels dashboard. Lynx bulk caching is managed for you.

Architecture

Everything hangs off ModularOpMode, a base OpMode you extend. In its preload() hook you register subsystems and install modules; from then on ModularOpMode drives every registered part through the same lifecycle — init(), init_loop(), start(), update()/loop(), and stop() — in registration order. On top of that sit the task system for command-like sequencing and the binding manager for gamepad input. The pieces:

Core

ModularOpMode

The base OpMode. Drives registered subsystems and installed modules through their lifecycles and manages Lynx bulk caching so each loop is a single bulk read.

Structure

Subsystems

Self-contained units of robot behavior (drive, lift, intake). Each implements init, init_loop, start, update, and stop, and is driven automatically once registered.

Hardware

Devices

Thin wrappers over SDK hardware — motors, servos, CR servos, and sensors (IMU, color, distance, touch, analog/digital, REV Color Sensor V3) — that subsystems compose.

Control

Controllers

PID, feedforward, and composable controllers that turn a target and a measurement into a motor output — the closed-loop math your subsystems reuse.

Input

Bindings

Declarative gamepad button and analog bindings (including toggles), registered against the shared bindingManager so input handling stays out of your loop.

Sequencing

Tasks

A command-like system: sequential, parallel, race, deadline, repeat, deferred, and path-following tasks, run by the OpMode's task master each loop.

Composition

Modules

Reusable OpMode-level behaviors (such as binding and Pedro TeleOp drive modules) installed with installModule(...) and driven alongside subsystems.

Output

Telemetry

A telemetry manager for organizing driver-station and dashboard output cleanly across subsystems and modules.

How a robot program is organized

A CDALib robot program starts from a single OpMode class that extends ModularOpMode. You annotate it with @TeleOp or @Autonomous (and optionally @Photon), and you override one method — preload().

Inside preload() you build the robot: construct your subsystems from the hardwareMap and register each one with registerSubsystem(...); install any modules with installModule(...); and wire gamepad input through the protected bindingManager field. From that point on the OpMode owns the lifecycle — when the driver hits INIT, every subsystem and module is initialized in registration order; while the driver waits on the init screen, their init_loop() runs; on PLAY, start() fires; and every cycle the OpMode clears the Lynx bulk cache once, then calls each subsystem's update() and each module's loop(), and advances any running tasks.

Because each subsystem owns its own devices and closed-loop control, and each task encapsulates a step of a routine, your OpMode stays small — it wires parts together rather than doing the work itself. The same subsystems and tasks are reused across TeleOp and autonomous OpModes.