Class AutoDrive

java.lang.Object
com.crossbotics.ftchelper.drive.AutoDrive

public class AutoDrive extends Object
Autonomous moves for a mecanum OR standard (tank) robot, using the wheel encoders and the IMU. (This was the blocking part of last season's Drivebase.)

An encoder is a sensor on the motor that counts how far it has turned (in "ticks"). The IMU is the sensor in the Control Hub that knows which way the robot is facing (its "heading").

Standard (tank) drive can only move forward and back (direction 0 or 180) and turn; sideways moves and moveWithTurn(double, double, double, double, double) throw an error, because the robot cannot do them.

BLOCKING ON PURPOSE: each move/turn method WAITS until the move ends, so use these only in a LinearOpMode autonomous, never in TeleOp. Your mechanisms keep working during a move through setLoopHook(java.lang.Runnable) (or AutoRoutine, which does that for you). Each one stops when it is done, when it is stuck, when it times out, or when the OpMode stops. The motors are always stopped at the end. No wheel ever gets more than DriveConfig.powerLimit. Why waiting is fine here and nowhere else: docs/guides/non-blocking.md.


 AutoDrive auto = new AutoDrive(this, driveConfig, autoConfig, imu);
 waitForStart();
 auto.move(24, 0, 0.6);      // 24 inches forward
 auto.move(12, 90, 0.5);     // 12 inches right
 auto.turn(90, 0.5);         // turn 90 degrees left
 auto.turnTo(0, 0.5);        // face the starting direction again
 

Directions in move(double, double, double): 0 = forward, 90 = right, 180 = back, -90 = left (clockwise). Turns: positive = left (counterclockwise), like the IMU. The full sign rules: docs/conventions.md. Docs: docs/modules/drive.md (section "AutoDrive"). Tutorial 09 builds a first autonomous with it.

  • Constructor Details

    • AutoDrive

      public AutoDrive(com.qualcomm.robotcore.eventloop.opmode.LinearOpMode opMode, DriveConfig driveConfig, AutoDriveConfig autoConfig, com.qualcomm.robotcore.hardware.IMU imu)
      Sets up the four drive motors (encoders reset, RUN_USING_ENCODER, brake, power 0). Brake means the wheels hold still at power 0 instead of rolling, so the robot stops where the move ends. Encoders are reset so every autonomous starts counting from 0.
      Parameters:
      opMode - your autonomous OpMode, usually this
      driveConfig - motor names, directions and power limit (the same one TeleOp uses)
      autoConfig - tuning; calibrationConfirmed must be true
      imu - a started IMU, e.g. from ImuSetup.get(com.qualcomm.robotcore.hardware.HardwareMap, java.lang.String, com.qualcomm.hardware.rev.RevHubOrientationOnRobot.LogoFacingDirection, com.qualcomm.hardware.rev.RevHubOrientationOnRobot.UsbFacingDirection)
      Throws:
      IllegalStateException - if autoConfig.calibrationConfirmed is false
    • AutoDrive

      public AutoDrive(AutoDriveConfig cfg, boolean tank, double powerLimit, com.qualcomm.robotcore.hardware.DcMotorEx fl, com.qualcomm.robotcore.hardware.DcMotorEx fr, com.qualcomm.robotcore.hardware.DcMotorEx bl, com.qualcomm.robotcore.hardware.DcMotorEx br, DoubleSupplier headingCcwDeg, Runnable headingReset, BooleanSupplier isActive, Runnable idle, Consumer<String> log, LongSupplier clockNanos)
      For tests and simulations (no robot needed): everything AutoDrive needs, given directly. The motors must already be set up (directions, encoder mode). For a 2-motor tank drive, bl and br are null.
      Parameters:
      headingCcwDeg - gives the heading in degrees, counterclockwise positive
      isActive - gives false once the OpMode should stop
      clockNanos - gives the time now in nanoseconds (a fake clock in tests)
  • Method Details

    • setLoopHook

      public void setLoopHook(Runnable hook)
      Runs your code once per loop during every move and turn. Use it to keep other mechanisms working while the robot drives (for example a lift PID or a flywheel). The code must be quick. Pass null to remove it.
    • setStopCondition

      public void setStopCondition(BooleanSupplier condition)
      An extra reason to stop a move early: when this is true, the move ends with STOPPED. AutoRoutine uses it to end the main part of autonomous on time for parking. Pass null to remove it.
    • move

      public AutoDrive.Result move(double distanceIn, double directionDeg, double maxPower)
      Drives a distance in a straight line, robot-relative, without turning. Full speed until the last part, then slows down (see taperStartFraction).

      BLOCKS (on purpose): returns when the move ends. Autonomous only; never in TeleOp.

      Parameters:
      distanceIn - inches. A negative distance goes the opposite way.
      directionDeg - robot-relative direction: 0 forward, 90 right, 180 back, -90 left
      maxPower - 0.1 to 1 (0.3 to 0.7 is usual). Never more than the DriveConfig power limit.
      Returns:
      how the move ended: DONE, STALLED, TIMED_OUT or STOPPED
      Throws:
      IllegalArgumentException - on a standard (tank) drive, for any direction except 0 or 180
    • moveWithTurn

      public AutoDrive.Result moveWithTurn(double distanceIn, double fieldDirectionDeg, double targetHeadingDeg, double maxPower, double maxTurnPower)
      Drives a distance in a FIELD direction while turning to a heading at the same time. The direction stays fixed on the field even while the robot turns. If the move finishes (DONE) but the heading is not there yet, it finishes the turn, inside the same time limit. After a stall it does NOT turn.

      BLOCKS (on purpose): returns when the move ends. Autonomous only; never in TeleOp.

      Parameters:
      distanceIn - inches (negative = opposite way)
      fieldDirectionDeg - direction on the field, clockwise from where heading 0 points: 0 forward, 90 right, 180 back, -90 left
      targetHeadingDeg - heading to end at, IMU degrees (counterclockwise positive)
      maxPower - translation power, 0.1 to 1
      maxTurnPower - turn power, 0.1 to 1
      Returns:
      how the move ended: DONE, STALLED, TIMED_OUT or STOPPED
      Throws:
      UnsupportedOperationException - on a standard (tank) drive
    • driveTo

      public AutoDrive.Result driveTo(Supplier<FieldPose> pose, double xIn, double yIn, double headingDeg, double maxPower, double toleranceIn)
    • driveTo

      public AutoDrive.Result driveTo(Supplier<FieldPose> pose, BooleanSupplier ready, double xIn, double yIn, double headingDeg, double maxPower, double toleranceIn)
      driveTo(java.util.function.Supplier, double, double, double, double, double), checking every loop that the odometry works: if ready turns false, the robot stops at once (NO_ODOMETRY). Without it the robot would drive on a frozen pose until the time runs out.
    • turn

      public AutoDrive.Result turn(double degrees, double maxPower)
      Turns in place by an amount.

      BLOCKS (on purpose): returns when the move ends. Autonomous only; never in TeleOp.

      Parameters:
      degrees - positive = left (counterclockwise), negative = right
      maxPower - 0.2 to 1 (0.3 to 0.6 is usual)
      Returns:
      how the turn ended: DONE, TIMED_OUT or STOPPED
    • turnTo

      public AutoDrive.Result turnTo(double headingDeg, double maxPower)
      Turns in place to face a heading.

      BLOCKS (on purpose): returns when the move ends. Autonomous only; never in TeleOp.

      Parameters:
      headingDeg - target IMU heading, degrees (counterclockwise positive, 0 = start direction)
      maxPower - 0.2 to 1
      Returns:
      how the turn ended: DONE, TIMED_OUT or STOPPED
    • headingDeg

      public double headingDeg()
      The robot's heading, IMU degrees (counterclockwise positive).
    • resetHeading

      public void resetHeading()
      Sets the current heading to 0.
    • getWheelTicks

      public int[] getWheelTicks()
      Encoder counts, in the order front-left, front-right, back-left, back-right. On a 2-motor tank drive, the back values repeat the front ones.
    • stop

      public void stop()
      Stops all four wheels (brake).