VingVing Robot LogoVingVing Robot

Documentation v0.0.3

VingVing Robot Docs

Path Completion

Understanding when paths end and how to control completion behavior

How Path Completion Works

A path is considered "complete" when the robot reaches the endpoint within specified tolerances. Understanding completion criteria is crucial for reliable autonomous routines.

Completion Tolerances

// In RobotConfig - set how close is "close enough"
public static FollowerConstants followerConstants = new FollowerConstants()
    .completionTolerances(
        2.0,                     // X tolerance: within 2 inches
        2.0,                     // Y tolerance: within 2 inches
        Math.toRadians(5)        // Heading tolerance: within 5°
    );

// Path completes when robot is within ALL three tolerances

Choosing Tolerances:

  • Tight tolerances (0.5-1 inch): Precise scoring, takes longer to complete
  • Medium tolerances (2-3 inches): Balanced, good for most use cases
  • Loose tolerances (4-6 inches): Fast transitions, less accurate
  • Heading tolerance: Usually 2-10° depending on task requirements

Checking Path Status

// Standard path following loop
while (!follower.isPathComplete() && opModeIsActive()) {
    robot.update();
    follower.update();
    robot.setDrivePowers(follower.getMotorPowers());

    // Optional: monitor progress
    telemetry.addData("Path Progress", "%.1f%%", follower.getPathProgress() * 100);
    telemetry.addData("Distance to End", follower.getDistanceToEnd());
    telemetry.update();
}

// When loop exits, path is complete!
telemetry.addLine("✓ Path Complete");

Path End Callbacks

Execute Code on Path Completion:

Path pathWithEndAction = new BezierLine(new Point(48, 0, Point.CARTESIAN))
    .setConstantHeadingInterpolation(0)
    .setPathEndCallback(() -> {
        // Automatically called when path completes
        telemetry.addLine("Arrived at destination!");
        intake.setPower(0);
        arm.setTargetPosition(SCORE_POSITION);
    });

// No need to manually check completion for callbacks

Callback vs. Manual Actions:

  • Callbacks: Execute automatically, cleaner code, no manual checking
  • Manual (after loop): More control, easier to debug, explicit flow
  • Both work - choose based on preference and complexity

Timeout Handling

Preventing Infinite Loops:

// Add timeout safety to prevent getting stuck
ElapsedTime timer = new ElapsedTime();
double timeoutSeconds = 5.0;

follower.followPath(/* ... */);

while (!follower.isPathComplete() && opModeIsActive() && timer.seconds() < timeoutSeconds) {
    robot.update();
    follower.update();
    robot.setDrivePowers(follower.getMotorPowers());
}

if (timer.seconds() >= timeoutSeconds) {
    telemetry.addLine("⚠ Path timeout - continuing anyway");
    // Continue with autonomous (degraded but functional)
} else {
    telemetry.addLine("✓ Path completed successfully");
}

Multi-Path Completion

Chained Paths Complete Sequentially:

follower.followPath(
    path1,  // Completes when within tolerances
    path2,  // Then automatically starts
    path3   // Then this one
);

// Single loop waits for ALL paths to complete
while (!follower.isPathComplete() && opModeIsActive()) {
    robot.update();
    follower.update();
    robot.setDrivePowers(follower.getMotorPowers());

    // Check which segment is running
    int currentSegment = follower.getCurrentPathIndex();
    telemetry.addData("Path Segment", "%d / 3", currentSegment + 1);
}

// All three paths are now complete

Early Termination

Stopping Paths Before Completion:

// Stop path if condition met
while (!follower.isPathComplete() && opModeIsActive()) {
    robot.update();
    follower.update();

    // Emergency stop condition
    if (gamepad1.b || visionDetectsObstacle()) {
        follower.stopPath();  // Immediately halt
        break;
    }

    robot.setDrivePowers(follower.getMotorPowers());
}

// Resume with new path or handle abort
if (follower.isPathComplete()) {
    // Normal completion
} else {
    // Early termination - recovery logic
    telemetry.addLine("Path aborted - taking evasive action");
}

Practical Example

RobustAutonomous.java
@Autonomous
public class RobustAutonomous extends LinearOpMode {
    Robot robot;
    Follower follower;
    ElapsedTime timer = new ElapsedTime();

    @Override
    public void runOpMode() {
        robot = new Robot(hardwareMap, RobotConfig.class);
        robot.initializeLocalizer(hardwareMap);
        follower = new Follower(hardwareMap);

        waitForStart();

        // Path with completion callback
        follower.followPath(
            new BezierLine(new Point(30, 0, Point.CARTESIAN))
                .setConstantHeadingInterpolation(0)
                .setPathEndCallback(() -> {
                    telemetry.addLine("✓ Reached spike mark");
                    releasePixel();
                })
        );

        // Execute with timeout safety
        timer.reset();
        while (!follower.isPathComplete() && opModeIsActive() && timer.seconds() < 3.0) {
            robot.update();
            follower.update();
            robot.setDrivePowers(follower.getMotorPowers());

            // Real-time monitoring
            telemetry.addData("Progress", "%.0f%%", follower.getPathProgress() * 100);
            telemetry.addData("Distance Remaining", "%.1f in", follower.getDistanceToEnd());
            telemetry.addData("Time Elapsed", "%.1f s", timer.seconds());
            telemetry.update();
        }

        // Verify completion
        if (follower.isPathComplete()) {
            telemetry.addLine("✓ Path 1 Complete");
        } else {
            telemetry.addLine("⚠ Path 1 Timeout");
        }

        // Continue with autonomous...
    }
}

Completion Tips

💡 Tune Tolerances for Your Robot

Well-tuned PID allows tighter tolerances. If robot can't consistently reach 1-inch tolerance, either improve PID or use 2-3 inch tolerance.

💡 Always Use Timeouts

A robot stuck trying to complete an impossible path wastes the entire autonomous period. Timeouts ensure the routine continues even if one path fails.

💡 Log Completion Status

Add telemetry showing which paths completed vs. timed out. Helps identify problem paths during testing.