001// Copyright (c) FIRST and other WPILib contributors.
002// Open Source Software; you can modify and/or share it under the terms of
003// the WPILib BSD license file in the root directory of this project.
004
005package edu.wpi.first.wpilibj2.command;
006
007/**
008 * A robot subsystem. Subsystems are the basic unit of robot organization in the Command-based
009 * framework; they encapsulate low-level hardware objects (motor controllers, sensors, etc) and
010 * provide methods through which they can be used by {@link Command}s. Subsystems are used by the
011 * {@link CommandScheduler}'s resource management system to ensure multiple robot actions are not
012 * "fighting" over the same hardware; Commands that use a subsystem should include that subsystem in
013 * their {@link Command#getRequirements()} method, and resources used within a subsystem should
014 * generally remain encapsulated and not be shared by other parts of the robot.
015 *
016 * <p>Subsystems must be registered with the scheduler with the {@link
017 * CommandScheduler#registerSubsystem(Subsystem...)} method in order for the {@link
018 * Subsystem#periodic()} method to be called. It is recommended that this method be called from the
019 * constructor of users' Subsystem implementations. The {@link SubsystemBase} class offers a simple
020 * base for user implementations that handles this.
021 *
022 * <p>This class is provided by the NewCommands VendorDep
023 */
024public interface Subsystem {
025  /**
026   * This method is called periodically by the {@link CommandScheduler}. Useful for updating
027   * subsystem-specific state that you don't want to offload to a {@link Command}. Teams should try
028   * to be consistent within their own codebases about which responsibilities will be handled by
029   * Commands, and which will be handled here.
030   */
031  default void periodic() {}
032
033  /**
034   * This method is called periodically by the {@link CommandScheduler}. Useful for updating
035   * subsystem-specific state that needs to be maintained for simulations, such as for updating
036   * {@link edu.wpi.first.wpilibj.simulation} classes and setting simulated sensor readings.
037   */
038  default void simulationPeriodic() {}
039
040  /**
041   * Sets the default {@link Command} of the subsystem. The default command will be automatically
042   * scheduled when no other commands are scheduled that require the subsystem. Default commands
043   * should generally not end on their own, i.e. their {@link Command#isFinished()} method should
044   * always return false. Will automatically register this subsystem with the {@link
045   * CommandScheduler}.
046   *
047   * @param defaultCommand the default command to associate with this subsystem
048   */
049  default void setDefaultCommand(Command defaultCommand) {
050    CommandScheduler.getInstance().setDefaultCommand(this, defaultCommand);
051  }
052
053  /**
054   * Gets the default command for this subsystem. Returns null if no default command is currently
055   * associated with the subsystem.
056   *
057   * @return the default command associated with this subsystem
058   */
059  default Command getDefaultCommand() {
060    return CommandScheduler.getInstance().getDefaultCommand(this);
061  }
062
063  /**
064   * Returns the command currently running on this subsystem. Returns null if no command is
065   * currently scheduled that requires this subsystem.
066   *
067   * @return the scheduled command currently requiring this subsystem
068   */
069  default Command getCurrentCommand() {
070    return CommandScheduler.getInstance().requiring(this);
071  }
072
073  /**
074   * Registers this subsystem with the {@link CommandScheduler}, allowing its {@link
075   * Subsystem#periodic()} method to be called when the scheduler runs.
076   */
077  default void register() {
078    CommandScheduler.getInstance().registerSubsystem(this);
079  }
080
081  /**
082   * Constructs a command that runs an action once and finishes. Requires this subsystem.
083   *
084   * @param action the action to run
085   * @return the command
086   * @see InstantCommand
087   */
088  default CommandBase runOnce(Runnable action) {
089    return Commands.runOnce(action, this);
090  }
091
092  /**
093   * Constructs a command that runs an action every iteration until interrupted. Requires this
094   * subsystem.
095   *
096   * @param action the action to run
097   * @return the command
098   * @see RunCommand
099   */
100  default CommandBase run(Runnable action) {
101    return Commands.run(action, this);
102  }
103
104  /**
105   * Constructs a command that runs an action once and another action when the command is
106   * interrupted. Requires this subsystem.
107   *
108   * @param start the action to run on start
109   * @param end the action to run on interrupt
110   * @return the command
111   * @see StartEndCommand
112   */
113  default CommandBase startEnd(Runnable start, Runnable end) {
114    return Commands.startEnd(start, end, this);
115  }
116
117  /**
118   * Constructs a command that runs an action every iteration until interrupted, and then runs a
119   * second action. Requires this subsystem.
120   *
121   * @param run the action to run every iteration
122   * @param end the action to run on interrupt
123   * @return the command
124   */
125  default CommandBase runEnd(Runnable run, Runnable end) {
126    return Commands.runEnd(run, end, this);
127  }
128}