End Conditions
End conditions determine when a follower should stop executing.
The EndCondition
interface allows you to define custom logic
for when trajectory following should complete.
What are End Conditions?
End conditions are functions that return true
when
a follower should stop following a trajectory.
They provide a flexible way to control when trajectory execution completes,
beyond just reaching the end of the planned path.
Every follower accepts a set of end conditions that are checked on each loop iteration.
If any end condition returns true
,
the follower will stop and mark itself as done.
Default End Conditions
By default, followers use EndCondition.default
, which includes:
- Overtime condition: Stops if the trajectory runs 2 seconds longer than its planned duration
- Distance from end: Stops when the robot is within 2 inches of the trajectory's end position
Custom End Conditions
You can create custom end conditions by implementing the EndCondition
interface:
Built-in End Condition Factory Methods
The EndCondition
companion object provides several factory methods for common scenarios:
Time-based Conditions
// Stop if trajectory runs longer than planned duration + timeout
EndCondition.overTime(duration: Duration)
EndCondition.overTime(duration: java.time.Duration)
EndCondition.overTime(timeoutSeconds: Double)
// Examples:
val timeoutCondition = EndCondition.overTime(3.0) // 3 second timeout
val kotlinDurationTimeout = EndCondition.overTime(5.seconds)
// Stop if trajectory runs longer than planned duration + timeout
EndCondition.overTime(Duration duration)
EndCondition.overTime(java.time.Duration duration)
EndCondition.overTime(double timeoutSeconds)
// Examples:
EndCondition timeoutCondition = EndCondition.overTime(3.0); // 3 second timeout
EndCondition javaDurationTimeout = EndCondition.overTime(Duration.ofSeconds(5));
Position-based Conditions
Velocity-based Conditions
Combining Multiple Conditions
You can combine multiple end conditions to create sophisticated stopping logic:
val customEndConditions = setOf(
EndCondition.overTime(4.0), // 4 second timeout
EndCondition.dispFromEnd(1.0), // Within 1 inch of end
EndCondition.robotVel(1.5), // Robot moving slower than 1.5 in/s
EndCondition { gamepad1.a } // Manual stop with A button
)
val follower = TimeFollower(trajectory, drive, customEndConditions)
Set<EndCondition> customEndConditions = Set.of(
EndCondition.overTime(4.0), // 4 second timeout
EndCondition.dispFromEnd(1.0), // Within 1 inch of end
EndCondition.robotVel(1.5), // Robot moving slower than 1.5 in/s
follower -> gamepad1.a // Manual stop with A button
);
Follower follower = new TimeFollower(trajectory, drive, customEndConditions);
Common Use Cases
Emergency Stop
Create an end condition for emergency stops (note that gamepad input is not legal in the autonomous period of FTC matches):
Time Limits for Autonomous
Set strict time limits for autonomous periods:
Position Tolerance
Create custom position tolerances:
Best Practices
Always Include a Timeout
Never rely solely on position or velocity conditions - always include a timeout to prevent infinite loops:
Test End Conditions
Test your end conditions thoroughly, especially custom ones:
Use Appropriate Tolerances
Choose tolerances that match your robot's capabilities and requirements:
- Precise positioning: Use smaller distance tolerances (0.5-1.0 inches)
- General movement: Use larger distance tolerances (1.0-3.0 inches)
- Fast movements: Use velocity-based conditions to detect when movement stops
- Critical timing: Use strict time limits with appropriate buffers
End conditions are a powerful tool for creating robust and reliable autonomous routines. By combining different types of conditions, you can ensure your robot behaves predictably in various scenarios.