mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-21 01:01:43 +00:00
166 lines
5.5 KiB
Java
166 lines
5.5 KiB
Java
|
|
// Copyright (c) FIRST and other WPILib contributors.
|
||
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
||
|
|
// the WPILib BSD license file in the root directory of this project.
|
||
|
|
|
||
|
|
package org.wpilib.commands3;
|
||
|
|
|
||
|
|
import edu.wpi.first.units.measure.Time;
|
||
|
|
import java.util.List;
|
||
|
|
import java.util.function.Consumer;
|
||
|
|
import org.wpilib.annotation.NoDiscard;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generic base class to represent mechanisms on a robot. Commands can require sole ownership of a
|
||
|
|
* mechanism; when a command that requires a mechanism is running, no other commands may use it at
|
||
|
|
* the same time.
|
||
|
|
*
|
||
|
|
* <p>Even though this class is named "Mechanism", it may be used to represent other physical
|
||
|
|
* hardware on a robot that should be controlled with commands - for example, an LED strip or a
|
||
|
|
* vision processor that can switch between different pipelines could be represented as mechanisms.
|
||
|
|
*/
|
||
|
|
public class Mechanism {
|
||
|
|
private final String m_name;
|
||
|
|
|
||
|
|
private final Scheduler m_registeredScheduler;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates a new mechanism registered with the default scheduler instance and named using the name
|
||
|
|
* of the class. Intended to be used by subclasses to get sane defaults without needing to
|
||
|
|
* manually declare a constructor.
|
||
|
|
*/
|
||
|
|
@SuppressWarnings("this-escape")
|
||
|
|
protected Mechanism() {
|
||
|
|
m_name = getClass().getSimpleName();
|
||
|
|
m_registeredScheduler = Scheduler.getDefault();
|
||
|
|
setDefaultCommand(idle());
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates a new mechanism, registered with the default scheduler instance.
|
||
|
|
*
|
||
|
|
* @param name The name of the mechanism. Cannot be null.
|
||
|
|
*/
|
||
|
|
public Mechanism(String name) {
|
||
|
|
this(name, Scheduler.getDefault());
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates a new mechanism, registered with the given scheduler instance.
|
||
|
|
*
|
||
|
|
* @param name The name of the mechanism. Cannot be null.
|
||
|
|
* @param scheduler The registered scheduler. Cannot be null.
|
||
|
|
*/
|
||
|
|
@SuppressWarnings("this-escape")
|
||
|
|
public Mechanism(String name, Scheduler scheduler) {
|
||
|
|
m_name = name;
|
||
|
|
m_registeredScheduler = scheduler;
|
||
|
|
setDefaultCommand(idle());
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Gets the name of this mechanism.
|
||
|
|
*
|
||
|
|
* @return The name of the mechanism.
|
||
|
|
*/
|
||
|
|
@NoDiscard
|
||
|
|
public String getName() {
|
||
|
|
return m_name;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Sets the default command to run on the mechanism when no other command is scheduled. The
|
||
|
|
* default command's priority is effectively the minimum allowable priority for any command
|
||
|
|
* requiring a mechanism. For this reason, it's recommended that a default command have a priority
|
||
|
|
* less than {@link Command#DEFAULT_PRIORITY} so it doesn't prevent low-priority commands from
|
||
|
|
* running.
|
||
|
|
*
|
||
|
|
* <p>The default command is initially an idle command that only owns the mechanism without doing
|
||
|
|
* anything. This command has the lowest possible priority to allow any other command to run.
|
||
|
|
*
|
||
|
|
* @param defaultCommand the new default command
|
||
|
|
*/
|
||
|
|
public void setDefaultCommand(Command defaultCommand) {
|
||
|
|
m_registeredScheduler.setDefaultCommand(this, defaultCommand);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Gets the default command that was set by the latest call to {@link
|
||
|
|
* #setDefaultCommand(Command)}.
|
||
|
|
*
|
||
|
|
* @return The currently configured default command
|
||
|
|
*/
|
||
|
|
public Command getDefaultCommand() {
|
||
|
|
return m_registeredScheduler.getDefaultCommandFor(this);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Starts building a command that requires this mechanism.
|
||
|
|
*
|
||
|
|
* @param commandBody The main function body of the command.
|
||
|
|
* @return The command builder, for further configuration.
|
||
|
|
*/
|
||
|
|
public NeedsNameBuilderStage run(Consumer<Coroutine> commandBody) {
|
||
|
|
return new StagedCommandBuilder().requiring(this).executing(commandBody);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Starts building a command that requires this mechanism. The given function will be called
|
||
|
|
* repeatedly in an infinite loop. Useful for building commands that don't need state or multiple
|
||
|
|
* stages of logic.
|
||
|
|
*
|
||
|
|
* @param loopBody The body of the infinite loop.
|
||
|
|
* @return The command builder, for further configuration.
|
||
|
|
*/
|
||
|
|
public NeedsNameBuilderStage runRepeatedly(Runnable loopBody) {
|
||
|
|
return run(
|
||
|
|
coroutine -> {
|
||
|
|
while (true) {
|
||
|
|
loopBody.run();
|
||
|
|
coroutine.yield();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns a command that idles this mechanism until another command claims it. The idle command
|
||
|
|
* has {@link Command#LOWEST_PRIORITY the lowest priority} and can be interrupted by any other
|
||
|
|
* command.
|
||
|
|
*
|
||
|
|
* <p>The {@link #getDefaultCommand() default command} for every mechanism is an idle command
|
||
|
|
* unless a different default command has been configured.
|
||
|
|
*
|
||
|
|
* @return A new idle command.
|
||
|
|
*/
|
||
|
|
public Command idle() {
|
||
|
|
return run(Coroutine::park).withPriority(Command.LOWEST_PRIORITY).named(getName() + "[IDLE]");
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns a command that idles this mechanism for the given duration of time.
|
||
|
|
*
|
||
|
|
* @param duration How long the mechanism should idle for.
|
||
|
|
* @return A new idle command.
|
||
|
|
*/
|
||
|
|
public Command idleFor(Time duration) {
|
||
|
|
return idle().withTimeout(duration);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Gets all running commands that require this mechanism. Commands are returned in the order in
|
||
|
|
* which they were scheduled. The returned list is read-only. Every command in the list will have
|
||
|
|
* been scheduled by the previous entry in the list or by intermediate commands that do not
|
||
|
|
* require the mechanism.
|
||
|
|
*
|
||
|
|
* @return The currently running commands that require the mechanism.
|
||
|
|
*/
|
||
|
|
@NoDiscard
|
||
|
|
public List<Command> getRunningCommands() {
|
||
|
|
return m_registeredScheduler.getRunningCommandsFor(this);
|
||
|
|
}
|
||
|
|
|
||
|
|
@Override
|
||
|
|
public String toString() {
|
||
|
|
return m_name;
|
||
|
|
}
|
||
|
|
}
|