Class Action

java.lang.Object
com.crossbotics.ftchelper.robot.Action

public final class Action extends Object
Steps that use several parts together, written once (in Actions.java) and started by a button in TeleOp or used as a step in an autonomous.

 public static Action scoreHigh(Robot r) {
     return Action.named("Score high")
             .then(() -> r.lift.goTo("high"))
             .waitUntil("lift at the top", r.lift::isAtTarget, 2.0)
             .then(r.claw::open)
             .waitSeconds(0.3)
             .then(() -> r.lift.goTo("down"));
 }
 // Controls.java:  g2.y.press(Actions.scoreHigh(robot));
 // an autonomous:  s.action(Actions.scoreHigh(robot));
 
  • Never waits: an action does a little every loop, so the robot keeps driving and every other button keeps working while it runs.
  • Parts are claimed: the parts an action commands are its own while it runs. Another action that commands one of them stops it; so does the driver moving that part by hand (the driver always wins).
  • A wait that times out stops the action (a lift that never reached the top must not open the claw). The Driver Station says why.
  • A stopped action (cancelled, taken over, timed out) stops what it started, safely: a lift or arm holds its height, a turret its angle, waiting shots are dropped, an intake stops. An action that finishes keeps its last commands.
  • A part that is not on the robot yet (optional() in Robot.java, not in the configuration) is skipped: its commands do nothing, the waits right after a step that only used missing parts are skipped too, and the action goes on with the other parts. Its status says "skipped IntakeDeploy (not on the robot)"; an autonomous's report says it too.

() -> r.lift.goTo("high") is a small piece of code (a "lambda") that the action runs later, when it reaches that step. r.claw::open is the same for a method with no inputs. Docs: docs/modules/robot.md (section "Actions")

  • Method Details

    • named

      public static Action named(String name)
      Starts a new action.
      Parameters:
      name - shown on the Driver Station, e.g. "Score high"
    • then

      public Action then(Runnable... doNow)
      Does these at once, then goes to the next step. Several at once move several parts together: .then(() -> r.arm.goTo("grab"), r.claw::open).
      Parameters:
      doNow - one or more commands
    • waitSeconds

      public Action waitSeconds(double seconds)
      Waits this long (the robot keeps running), then goes on.
      Parameters:
      seconds - how long
    • waitUntil

      public Action waitUntil(String what, BooleanSupplier condition, double timeoutSec)
      Waits until something is true. If it is not true in timeoutSec, the action STOPS and the Driver Station says "timed out waiting for {what}".
      Parameters:
      what - a few words for the Driver Station, e.g. "lift at the top"
      condition - e.g. r.lift::isAtTarget
      timeoutSec - the most to wait, seconds
    • waitUntil

      public Action waitUntil(BooleanSupplier condition, double timeoutSec)
      waitUntil(String, BooleanSupplier, double) with "the condition" as its words.
    • name

      public String name()
      The name given to named(java.lang.String).
    • isRunning

      public boolean isRunning()
      True while it runs.
    • result

      public String result()
      How the last run ended: "done", "cancelled", "stopped: Lift moved by hand"... ("" before the first).
    • skipped

      public List<String> skipped()
      The parts this run (or the last one) skipped because they are not on the robot (marked optional() in Robot.java and missing from the configuration), e.g. ["IntakeDeploy"]. Empty when every part was there.
    • status

      public String status()
      E.g. "Score high: step 2 of 5 (lift at the top)", or its last result when not running.