This is the first year my team has wired a pneumatics system that uses a double solenoid. I have programmed a Subsystem and Command to allow for a button to extend the piston and another to retract it. The compressor is not activating at all though. Does my code look correct? I’m not sure if this is a code error, or if it’s a potential wiring problem. We have used the Phoenix tuner to verify that the Pneumatic Control Module is, in fact, set to CAN ID 0 – so I think the DoubleSolenoid
object instantiation is correct. Below is the code:
The Subsystem
:
package frc.robot.subsystems;
import edu.wpi.first.wpilibj.DoubleSolenoid;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
public class PneumaticsSubsystem extends SubsystemBase {
/*
The Pneumatics Control Module (PCM) we will be using has
been given the default CAN id of 0. This means we do not
have to specify an id in the DoubleSolenoid constructor.
In the DoubleSolenoid constructor, we only need to specify
the port numbers on which the double solenoid is connected
to the PCM (in our case, 1 and 2).
*/
private DoubleSolenoid doubleSolenoid = new DoubleSolenoid(1, 2);
/**
* Creates a new PneumaticsSubsystem.
*/
public PneumaticsSubsystem() {
super(); //add this
}
@Override
public void periodic() {
// This method will be called once per scheduler run
}
public void extendPiston() {
//Should extend the piston
doubleSolenoid.set(DoubleSolenoid.Value.kForward);
}
public void retractPiston() {
//Should retract the piston
doubleSolenoid.set(DoubleSolenoid.Value.kReverse);
}
}
Below are the Command
classes that trigger the extend and retract functionalities:
package frc.robot.commands;
import edu.wpi.first.wpilibj2.command.CommandBase;
import frc.robot.subsystems.PneumaticsSubsystem;
public class PneumaticsRetractPistonCommand extends CommandBase {
private PneumaticsSubsystem pneumaticsSubsystem = new PneumaticsSubsystem();
/**
* Creates a new PneumaticsRetractPistonCommand.
*/
public PneumaticsRetractPistonCommand(PneumaticsSubsystem pneumaticsSubsystem) {
// Use addRequirements() here to declare subsystem dependencies.
this.pneumaticsSubsystem = pneumaticsSubsystem;
addRequirements(this.pneumaticsSubsystem);
}
// Called when the command is initially scheduled.
@Override
public void initialize() {
}
// Called every time the scheduler runs while the command is scheduled.
@Override
public void execute() {
pneumaticsSubsystem.retractPiston();
}
// Called once the command ends or is interrupted.
@Override
public void end(boolean interrupted) {
}
// Returns true when the command should end.
@Override
public boolean isFinished() {
return false;
}
}
package frc.robot.commands;
import edu.wpi.first.wpilibj2.command.CommandBase;
import frc.robot.subsystems.PneumaticsSubsystem;
public class PneumaticsExtendPistonCommand extends CommandBase {
//Member variables will be subsystems that the command will be executed on:
PneumaticsSubsystem pneumaticsSubsystem;
//Pass in an instance of all the required subsystems in the constructor.
//and set them to the member variables.
public PneumaticsExtendPistonCommand(PneumaticsSubsystem pneumatics) {
// Use addRequirements() here to declare subsystem dependencies.
pneumaticsSubsystem = pneumatics;
addRequirements(pneumaticsSubsystem);
}
// Called when the command is initially scheduled.
@Override
public void initialize() {
}
// Called every time the scheduler runs while the command is scheduled.
@Override
public void execute() {
pneumaticsSubsystem.extendPiston(); //This is the command to execute -- extend the piston
}
// Called once the command ends or is interrupted.
@Override
public void end(boolean interrupted) {
}
// Returns true when the command should end.
@Override
public boolean isFinished() {
return false;
}
}
Below is the RobotContainer
class:
public class RobotContainer {
/*
Specify what port (as labeled on the FRC Driver's Station)
the physical controller is connected to. This is listed in
the Driver Station's "USB order list". If the controller is
the only thing attached to the computer, then the port is
almost always 0. You should double check, though.
*/
public static Joystick controller = new Joystick(0); //This variable represents the physical game controller
//Pneumatics Subsystems and Commands
PneumaticsSubsystem pneumaticsSubsystem = new PneumaticsSubsystem();
PneumaticsExtendPistonCommand pneumaticsExtendPistonCommand = new PneumaticsExtendPistonCommand(pneumaticsSubsystem);
PneumaticsRetractPistonCommand pneumaticsRetractPistonCommand = new PneumaticsRetractPistonCommand(pneumaticsSubsystem);
// The robot's subsystems and commands are defined here...
private final ExampleSubsystem m_exampleSubsystem = new ExampleSubsystem();
private final ExampleCommand m_autoCommand = new ExampleCommand(m_exampleSubsystem);
/**
* The container for the robot. Contains subsystems, OI devices, and commands.
*/
public RobotContainer() {
// Configure the button bindings
configureButtonBindings();
}
/**
* Use this method to define your button->command mappings. Buttons can be created by
* instantiating a {@link GenericHID} or one of its subclasses ({@link
* edu.wpi.first.wpilibj.Joystick} or {@link XboxController}), and then passing it to a
* {@link edu.wpi.first.wpilibj2.command.button.JoystickButton}.
*/
private void configureButtonBindings() {
//Map buttons 3 and 4 on the controller to extend and retract the piston, respectively:
final JoystickButton extendPistonButton = new JoystickButton(controller, 3);
final JoystickButton retractPistonButton = new JoystickButton(controller, 4);
//Define each button's behaviour:
extendPistonButton.whenHeld(pneumaticsExtendPistonCommand);
retractPistonButton.whenHeld(pneumaticsRetractPistonCommand);
}
/**
* Use this to pass the autonomous command to the main {@link Robot} class.
*
* @return the command to run in autonomous
*/
public Command getAutonomousCommand() {
// An ExampleCommand will run in autonomous
return m_autoCommand;
}
}
Any help is tremendously appreciated!