NODO API Reference

A quick reference for NODO’s drivetrain functions.

For a complete explanation of how to build an autonomous, see Building Your First Autonomous.


Drive Commands

These are the core commands used to build an autonomous.

driveFor()

Drive forward or backward for a set amount of time.

Java

drive.driveFor(power, timeMs, this::opModeIsActive);
Argument Type Description
power double Motor power from -1.0 to 1.0
timeMs long Movement duration in milliseconds
active BooleanSupplier Stops the movement when the OpMode is no longer active

Examples

// Forward at 50% power for 800 ms
drive.driveFor(0.5, 800, this::opModeIsActive);

// Backward at 40% power for 500 ms
drive.driveFor(-0.4, 500, this::opModeIsActive);

The robot automatically attempts to maintain its heading while driving.


strafeFor()

Strafe left or right for a set amount of time.

Mecanum only.

Java

drive.strafeFor(power, timeMs, this::opModeIsActive);
Argument Type Description
power double Strafe power from -1.0 to 1.0
timeMs long Movement duration in milliseconds
active BooleanSupplier Stops the movement when the OpMode is no longer active

Direction

  • Positive → right
  • Negative → left

Example

drive.strafeFor(0.5, 700, this::opModeIsActive);

NODO uses IMU heading control while strafing.


turnBy()

Turn the robot by a relative angle.

Java

drive.turnBy(degrees, this::opModeIsActive);
Argument Type Description
degrees double Relative turn angle
active BooleanSupplier Stops the turn when the OpMode is no longer active

Direction

  • Positive → typically counterclockwise
  • Negative → typically clockwise

Examples

drive.turnBy(90, this::opModeIsActive);

drive.turnBy(-90, this::opModeIsActive);

turnBy(90) means turn 90° from the current heading, not “face 90° on the field.”

Turns use the configured turn PD controller.


waitFor()

Pause the autonomous while keeping the drivetrain stopped.

Java

drive.waitFor(timeMs, this::opModeIsActive);
Argument Type Description
timeMs long Wait duration in milliseconds
active BooleanSupplier Stops waiting when the OpMode is no longer active

Example

drive.waitFor(250, this::opModeIsActive);

Drive Configuration

Configuration should be completed before waitForStart().


setControlHubOrientation()

Tell NODO how the Control Hub is mounted on the robot.

Java

drive.setControlHubOrientation(
    LogoFacingDirection.UP,
    UsbFacingDirection.FORWARD
);
Argument Description
logoFacing Direction the REV logo faces
usbFacing Direction the USB ports face

Valid directions:

UP
DOWN
FORWARD
BACKWARD
LEFT
RIGHT

The orientation must match the physical mounting of the Control Hub.

Incorrect orientation can cause incorrect heading readings or turns in the wrong direction.


setExpansionHubOrientation()

Configure the orientation of an optional Expansion Hub IMU.

Java

drive.setExpansionHubOrientation(
    LogoFacingDirection.UP,
    UsbFacingDirection.FORWARD
);

Only configure this when using an Expansion Hub IMU.


setMecanumMotorDirections()

Set the direction of each mecanum motor.

Java

drive.setMecanumMotorDirections(
    DcMotor.Direction.FORWARD, // front left
    DcMotor.Direction.REVERSE, // front right
    DcMotor.Direction.FORWARD, // back left
    DcMotor.Direction.REVERSE  // back right
);

Order:

Front Left
Front Right
Back Left
Back Right

Positive forward power should make the robot physically move forward.


setTankMotorDirections()

Set the direction of the two tank drivetrain motors.

drive.setTankMotorDirections(
    DcMotor.Direction.FORWARD,
    DcMotor.Direction.REVERSE
);

Order:

Left
Right

setMotorNames()

Set custom hardware-map motor names.

Use this before constructing the drive.

Mecanum

NODOChassis.setMotorNames(
    "frontLeft",
    "frontRight",
    "backLeft",
    "backRight"
);

Default names

frontLeft
frontRight
backLeft
backRight

Tank

leftDrive
rightDrive

If your Robot Controller configuration uses different names, replace the defaults with your names.


Turn Control

NODO uses a PD controller for IMU-based turns.


setTurnPD()

Configure the turn controller.

Java

drive.setTurnPD(kP, kD);

or:

drive.setTurnPD(kP, kD, maxPower);
Argument Description
kP Proportional gain
kD Derivative gain
maxPower Maximum turn motor power

Example

drive.setTurnPD(0.04, 0.0025, 0.4);

Starting values

Setting Starting value
kP 0.035
kD 0.002
maxPower 0.35

These are starting points, not universal values.


setTurnToleranceDegrees()

Set how close the robot must be to the target heading.

drive.setTurnToleranceDegrees(3.0);

Example:

Target:     90°
Tolerance:  3°

Accepted range:
87° → 93°

setTurnSettleMs()

Set how long the robot must remain within the turn tolerance before the turn is considered complete.

drive.setTurnSettleMs(150);

A longer settle time can make the turn more stable but increases autonomous time.


getTurnPD()

Access the turn controller directly.

drive.getTurnPD()
    .setPD(0.04, 0.0025)
    .setMaxPower(0.4)
    .setToleranceDegrees(3.0);

Use the individual setter functions if you prefer simpler configuration.


Heading

getHeading()

Return the filtered heading.

double heading = drive.getHeading();

Useful for telemetry and display.


getRawHeading()

Return the raw IMU heading.

double heading = drive.getRawHeading();

Useful for debugging IMU behavior and turns.


TeleOp / Manual Drive

NODO can also control the drivetrain during TeleOp.


setMecanumPowers()

Directly set the four mecanum motor powers.

chassis.setMecanumPowers(
    frontLeft,
    frontRight,
    backLeft,
    backRight
);

Example:

chassis.setMecanumPowers(fl, fr, bl, br);

Power values are generally between -1.0 and 1.0.


setPowers()

Set left and right tank drivetrain power.

tank.setPowers(left, right);

resetYaw()

Reset the heading reference.

chassis.resetYaw();

This can be useful during TeleOp when you want to redefine the current robot heading as zero.


NODODrive

NODODrive is the general drivetrain wrapper.

It allows a program to select mecanum or tank drive through the same class.

Constructor

NODODrive drive = new NODODrive(
    hardwareMap,
    NODODriveType.MECANUM,
    0.03
);
Argument Description
hardwareMap FTC hardware map
NODODriveType MECANUM or TANK
kF Static drivetrain feedforward

Drive types

NODODriveType.MECANUM
NODODriveType.TANK

kF

kF is the small static feedforward used to help the drivetrain overcome friction.

Typical starting value:

0.03

Example:

NODODrive drive = new NODODrive(
    hardwareMap,
    NODODriveType.MECANUM,
    0.03
);

If kF is too low

The robot may:

  • Struggle to start moving
  • Feel sluggish at low power

If kF is too high

The robot may:

  • Jump or twitch when starting
  • Feel aggressive near zero power

kF is for the drivetrain. It should not be applied to arms, slides, or other mechanisms.


NODORoutine

NODORoutine is optional.

You do not need it to build an autonomous.

Use direct drivetrain helpers if you want the simplest approach.

Create a routine

NODORoutine routine = new NODORoutine(chassis)
    .drive(0.5, 800)
    .waitMs(200)
    .turnTo(90)
    .drive(0.4, 500);

drive()

Add a timed drive step.

routine.drive(power, timeMs);

Example:

routine.drive(0.5, 800);

waitMs()

Add a wait step.

routine.waitMs(timeMs);

Example:

routine.waitMs(200);

turnTo()

Add a relative turn step.

routine.turnTo(degrees);

Example:

routine.turnTo(90);

start()

Start the routine.

routine.start();

Call this when the OpMode starts.


loop()

Advance the routine by one scheduler cycle.

routine.loop();

Call this from the OpMode’s loop() method.


isFinished()

Check whether every routine step has completed.

if (routine.isFinished()) {
    // autonomous is complete
}

cancelAll()

Stop and cancel the routine.

routine.cancelAll();

Usually called from stop().


FTC Blocks Quick Reference

Blocks are split into two toolbox groups:

  • NODO Init — setup before Start (motor names, init, IMU orientation, turn tuning)
  • NODO Run — movement after Start (drive, strafe, turn, wait)

Motor directions are plain text: type FORWARD or REVERSE (no separate direction enum block).

NODO Init

Blocks block Purpose
setFeedforward Set kF before/after init (default 0.03)
setMecanum Mecanum motor names + 4 directions
setTank Tank motor names + directions
initializeMecanumDrive Initialize mecanum drive
initializeTankDrive Initialize tank drive
setControlHubOrientation Configure Control Hub orientation
setExpansionHubOrientation Optional Expansion Hub IMU (mecanum)
setTurnPD Turn kP + kD (2 inputs) or kP/kD/max (3)

NODO Run

Blocks block Purpose
driveFor Timed drive: power, milliseconds
strafeFor Timed strafe: power, milliseconds (mecanum)
turnBy Relative turn (degrees, not time)
waitFor Pause (milliseconds)
getHeading Read gyro heading (degrees)
stopDriveMotors Stop all drive motors immediately

Example (matches SampleDriveAndTurn90)

[Init — before Start]

setFeedforward(0.03)

setMecanum("FL", "FR", "BL", "BR",
           "FORWARD", "REVERSE", "FORWARD", "REVERSE")

initializeMecanumDrive

setControlHubOrientation("UP", "FORWARD")

setTurnPD(0.04, 0.0025)

        ↓ START

[Run — stack once, not inside repeat-while]

driveFor(0.5, 800)

turnBy(90)

getHeading

Blocks does not require NODORoutine. Put Init blocks in the Init section; stack Run blocks once after Start (not inside repeat while opModeIsActive).


Common Patterns

Simple autonomous

drive.driveFor(0.5, 800, this::opModeIsActive);
drive.turnBy(90, this::opModeIsActive);
drive.driveFor(0.4, 500, this::opModeIsActive);

Drive → mechanism → drive

drive.driveFor(0.5, 800, this::opModeIsActive);

// Your mechanism code here
arm.setPower(1.0);

drive.waitFor(300, this::opModeIsActive);

drive.driveFor(-0.4, 500, this::opModeIsActive);

Drive → strafe → turn

drive.driveFor(0.5, 700, this::opModeIsActive);
drive.strafeFor(0.4, 500, this::opModeIsActive);
drive.turnBy(-90, this::opModeIsActive);

Quick Setup Reference

For a new Java autonomous:

// 1. Configure motor names if necessary

NODOChassis.setMotorNames(
    "frontLeft",
    "frontRight",
    "backLeft",
    "backRight"
);

// 2. Create drive

NODODrive drive = new NODODrive(
    hardwareMap,
    NODODriveType.MECANUM,
    0.03
);

// 3. Configure IMU

drive.setControlHubOrientation(
    LogoFacingDirection.UP,
    UsbFacingDirection.FORWARD
);

// 4. Configure motor directions

drive.setMecanumMotorDirections(
    DcMotor.Direction.FORWARD,
    DcMotor.Direction.REVERSE,
    DcMotor.Direction.FORWARD,
    DcMotor.Direction.REVERSE
);

// 5. Optional: tune turns

drive.setTurnPD(0.035, 0.002, 0.35);

// 6. Start autonomous

waitForStart();

if (isStopRequested()) return;

// 7. Build your sequence

drive.driveFor(0.5, 800, this::opModeIsActive);
drive.turnBy(90, this::opModeIsActive);
drive.driveFor(0.4, 500, this::opModeIsActive);

At a Glance

DRIVE
driveFor()
strafeFor()

TURN
turnBy()

TIMING
waitFor()

CONFIGURATION
setControlHubOrientation()
setExpansionHubOrientation()
setMecanumMotorDirections()
setTankMotorDirections()
setMotorNames()

TURN TUNING
setTurnPD()
setTurnToleranceDegrees()
setTurnSettleMs()
getTurnPD()

HEADING
getHeading()
getRawHeading()
resetYaw()

TELEOP
setMecanumPowers()
setPowers()

OPTIONAL ROUTINES
NODORoutine
.drive()
.waitMs()
.turnTo()
.start()
.loop()
.isFinished()
.cancelAll()

Need an Explanation?

This page is intended as a quick reference.

For step-by-step instructions:


This site uses Just the Docs, a documentation theme for Jekyll.