mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-20 00:51:42 +00:00
[examples] Improve Pneumatics example coverage in Solenoid and RapidReactCmdBot examples (#4998)
This commit is contained in:
@@ -40,6 +40,10 @@ void RapidReactCommandBot::ConfigureBindings() {
|
||||
m_storage.RunCommand())
|
||||
// Since we composed this inline we should give it a name
|
||||
.WithName("Shoot"));
|
||||
|
||||
// Toggle compressor with the Start button
|
||||
m_driverController.Start().ToggleOnTrue(
|
||||
m_pneumatics.DisableCompressorCommand());
|
||||
}
|
||||
|
||||
frc2::CommandPtr RapidReactCommandBot::GetAutonomousCommand() {
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// 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.
|
||||
|
||||
#include "subsystems/Pneumatics.h"
|
||||
|
||||
Pneumatics::Pneumatics() {}
|
||||
|
||||
frc2::CommandPtr Pneumatics::DisableCompressorCommand() {
|
||||
return StartEnd(
|
||||
[&] {
|
||||
// Disable closed-loop mode on the compressor.
|
||||
m_compressor.Disable();
|
||||
},
|
||||
[&] {
|
||||
// Enable closed-loop mode based on the digital pressure switch
|
||||
// connected to the PCM/PH. The switch is open when the pressure is over
|
||||
// ~120 PSI.
|
||||
m_compressor.EnableDigital();
|
||||
});
|
||||
}
|
||||
|
||||
units::pounds_per_square_inch_t Pneumatics::GetPressure() {
|
||||
// Get the pressure (in PSI) from an analog pressure sensor connected to
|
||||
// the RIO.
|
||||
return units::pounds_per_square_inch_t{m_pressureTransducer.Get()};
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "Constants.h"
|
||||
#include "subsystems/Drive.h"
|
||||
#include "subsystems/Intake.h"
|
||||
#include "subsystems/Pneumatics.h"
|
||||
#include "subsystems/Shooter.h"
|
||||
#include "subsystems/Storage.h"
|
||||
|
||||
@@ -45,6 +46,7 @@ class RapidReactCommandBot {
|
||||
Intake m_intake;
|
||||
Shooter m_shooter;
|
||||
Storage m_storage;
|
||||
Pneumatics m_pneumatics;
|
||||
|
||||
// The driver's controller
|
||||
frc2::CommandXboxController m_driverController{
|
||||
|
||||
@@ -28,7 +28,9 @@ class Intake : public frc2::SubsystemBase {
|
||||
|
||||
private:
|
||||
frc::PWMSparkMax m_motor{IntakeConstants::kMotorPort};
|
||||
frc::DoubleSolenoid m_piston{frc::PneumaticsModuleType::REVPH,
|
||||
|
||||
// Double solenoid connected to two channels of a PCM with the default CAN ID
|
||||
frc::DoubleSolenoid m_piston{frc::PneumaticsModuleType::CTREPCM,
|
||||
IntakeConstants::kSolenoidPorts[0],
|
||||
IntakeConstants::kSolenoidPorts[1]};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <frc/AnalogPotentiometer.h>
|
||||
#include <frc/Compressor.h>
|
||||
#include <frc/PneumaticsControlModule.h>
|
||||
#include <frc2/command/CommandPtr.h>
|
||||
#include <frc2/command/SubsystemBase.h>
|
||||
#include <units/pressure.h>
|
||||
|
||||
#include "Constants.h"
|
||||
|
||||
class Pneumatics : frc2::SubsystemBase {
|
||||
public:
|
||||
Pneumatics();
|
||||
/** Returns a command that disables the compressor indefinitely. */
|
||||
[[nodiscard]] frc2::CommandPtr DisableCompressorCommand();
|
||||
|
||||
/**
|
||||
* Query the analog pressure sensor.
|
||||
*
|
||||
* @return the measured pressure, in PSI
|
||||
*/
|
||||
units::pounds_per_square_inch_t GetPressure();
|
||||
|
||||
private:
|
||||
// External analog pressure sensor
|
||||
// product-specific voltage->pressure conversion, see product manual
|
||||
// in this case, 250(V/5)-25
|
||||
// the scale parameter in the AnalogPotentiometer constructor is scaled from
|
||||
// 1 instead of 5, so if r is the raw AnalogPotentiometer output, the
|
||||
// pressure is 250r-25
|
||||
static constexpr double kScale = 250;
|
||||
static constexpr double kOffset = -25;
|
||||
frc::AnalogPotentiometer m_pressureTransducer{/* the AnalogIn port*/ 2,
|
||||
kScale, kOffset};
|
||||
|
||||
// Compressor connected to a PH with a default CAN ID
|
||||
frc::Compressor m_compressor{frc::PneumaticsModuleType::CTREPCM};
|
||||
};
|
||||
@@ -2,69 +2,96 @@
|
||||
// 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.
|
||||
|
||||
#include <frc/DoubleSolenoid.h>
|
||||
#include <frc/Joystick.h>
|
||||
#include <frc/PneumaticsControlModule.h>
|
||||
#include <frc/Solenoid.h>
|
||||
#include <frc/TimedRobot.h>
|
||||
#include "Robot.h"
|
||||
|
||||
/**
|
||||
* This is a sample program showing the use of the solenoid classes during
|
||||
* operator control.
|
||||
*
|
||||
* Three buttons from a joystick will be used to control two solenoids: One
|
||||
* button to control the position of a single solenoid and the other two buttons
|
||||
* to control a double solenoid.
|
||||
*
|
||||
* Single solenoids can either be on or off, such that the air diverted through
|
||||
* them goes through either one channel or the other.
|
||||
*
|
||||
* Double solenoids have three states: Off, Forward, and Reverse. Forward and
|
||||
* Reverse divert the air through the two channels and correspond to the on and
|
||||
* off of a single solenoid, but a double solenoid can also be "off", where both
|
||||
* channels are diverted to exhaust such that there is no pressure in either
|
||||
* channel.
|
||||
*
|
||||
* Additionally, double solenoids take up two channels on your PCM whereas
|
||||
* single solenoids only take a single channel.
|
||||
*/
|
||||
class Robot : public frc::TimedRobot {
|
||||
public:
|
||||
void TeleopPeriodic() override {
|
||||
/* The output of GetRawButton is true/false depending on whether the button
|
||||
* is pressed; Set takes a boolean for for whether to use the default
|
||||
* (false) channel or the other (true).
|
||||
*/
|
||||
m_solenoid.Set(m_stick.GetRawButton(kSolenoidButton));
|
||||
#include <frc/shuffleboard/Shuffleboard.h>
|
||||
#include <units/pressure.h>
|
||||
|
||||
/* In order to set the double solenoid, we will say that if neither button
|
||||
* is pressed, it is off, if just one button is pressed, set the solenoid to
|
||||
* correspond to that button, and if both are pressed, set the solenoid to
|
||||
* Forwards.
|
||||
*/
|
||||
if (m_stick.GetRawButton(kDoubleSolenoidForward)) {
|
||||
m_doubleSolenoid.Set(frc::DoubleSolenoid::kForward);
|
||||
} else if (m_stick.GetRawButton(kDoubleSolenoidReverse)) {
|
||||
m_doubleSolenoid.Set(frc::DoubleSolenoid::kReverse);
|
||||
} else {
|
||||
m_doubleSolenoid.Set(frc::DoubleSolenoid::kOff);
|
||||
}
|
||||
void Robot::RobotInit() {
|
||||
// Publish elements to shuffleboard.
|
||||
frc::ShuffleboardTab& tab = frc::Shuffleboard::GetTab("Pneumatics");
|
||||
tab.Add("Single Solenoid", m_solenoid);
|
||||
tab.Add("Double Solenoid", m_doubleSolenoid);
|
||||
tab.Add("Compressor", m_compressor);
|
||||
|
||||
// Also publish some raw data
|
||||
tab.AddDouble("PH Pressure [PSI]", [&] {
|
||||
// Get the pressure (in PSI) from the analog sensor connected to the PH.
|
||||
// This function is supported only on the PH!
|
||||
// On a PCM, this function will return 0.
|
||||
units::pounds_per_square_inch_t pressure = m_compressor.GetPressure();
|
||||
return pressure.value();
|
||||
});
|
||||
tab.AddDouble("Compressor Current", [&] {
|
||||
// Get compressor current draw.
|
||||
units::ampere_t compressorCurrent = m_compressor.GetCurrent();
|
||||
return compressorCurrent.value();
|
||||
});
|
||||
tab.AddBoolean("Compressor Active", [&] {
|
||||
// Get whether the compressor is active.
|
||||
return m_compressor.IsEnabled();
|
||||
});
|
||||
tab.AddBoolean("Pressure Switch", [&] {
|
||||
// Get the digital pressure switch connected to the PCM/PH.
|
||||
// The switch is open when the pressure is over ~120 PSI.
|
||||
return m_compressor.GetPressureSwitchValue();
|
||||
});
|
||||
}
|
||||
|
||||
void Robot::TeleopPeriodic() {
|
||||
/*
|
||||
* The output of GetRawButton is true/false depending on whether
|
||||
* the button is pressed; Set takes a boolean for whether
|
||||
* to retract the solenoid (false) or extend it (true).
|
||||
*/
|
||||
m_solenoid.Set(m_stick.GetRawButton(kSolenoidButton));
|
||||
|
||||
/*
|
||||
* GetRawButtonPressed will only return true once per press.
|
||||
* If a button is pressed, set the solenoid to the respective channel.
|
||||
*/
|
||||
if (m_stick.GetRawButtonPressed(kDoubleSolenoidForward)) {
|
||||
m_doubleSolenoid.Set(frc::DoubleSolenoid::kForward);
|
||||
} else if (m_stick.GetRawButtonPressed(kDoubleSolenoidReverse)) {
|
||||
m_doubleSolenoid.Set(frc::DoubleSolenoid::kReverse);
|
||||
}
|
||||
|
||||
private:
|
||||
frc::Joystick m_stick{0};
|
||||
|
||||
// Solenoid corresponds to a single solenoid.
|
||||
frc::Solenoid m_solenoid{frc::PneumaticsModuleType::CTREPCM, 0};
|
||||
|
||||
// DoubleSolenoid corresponds to a double solenoid.
|
||||
frc::DoubleSolenoid m_doubleSolenoid{frc::PneumaticsModuleType::CTREPCM, 1,
|
||||
2};
|
||||
|
||||
static constexpr int kSolenoidButton = 1;
|
||||
static constexpr int kDoubleSolenoidForward = 2;
|
||||
static constexpr int kDoubleSolenoidReverse = 3;
|
||||
};
|
||||
// On button press, toggle the compressor with the mode selected from the
|
||||
// dashboard.
|
||||
if (m_stick.GetRawButtonPressed(kCompressorButton)) {
|
||||
// Check whether the compressor is currently enabled.
|
||||
bool isCompressorEnabled = m_compressor.IsEnabled();
|
||||
if (isCompressorEnabled) {
|
||||
// Disable closed-loop mode on the compressor.
|
||||
m_compressor.Disable();
|
||||
} else {
|
||||
// Change the if directives to select the closed-loop mode you want to
|
||||
// use:
|
||||
#if 0
|
||||
// Enable closed-loop mode based on the digital pressure switch
|
||||
// connected to the PCM/PH.
|
||||
m_compressor.EnableDigital();
|
||||
#endif
|
||||
#if 1
|
||||
// Enable closed-loop mode based on the analog pressure sensor connected
|
||||
// to the PH. The compressor will run while the pressure reported by the
|
||||
// sensor is in the specified range ([70 PSI, 120 PSI] in this example).
|
||||
// Analog mode exists only on the PH! On the PCM, this enables digital
|
||||
// control.
|
||||
m_compressor.EnableAnalog(70_psi, 120_psi);
|
||||
#endif
|
||||
#if 0
|
||||
// Enable closed-loop mode based on both the digital pressure switch AND the analog
|
||||
// pressure sensor connected to the PH.
|
||||
// The compressor will run while the pressure reported by the analog sensor is in the
|
||||
// specified range ([70 PSI, 120 PSI] in this example) AND the digital switch reports
|
||||
// that the system is not full.
|
||||
// Hybrid mode exists only on the PH! On the PCM, this enables digital control.
|
||||
m_compressor.EnableHybrid(70_psi, 120_psi);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef RUNNING_FRC_TESTS
|
||||
int main() {
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <frc/AnalogPotentiometer.h>
|
||||
#include <frc/Compressor.h>
|
||||
#include <frc/DoubleSolenoid.h>
|
||||
#include <frc/Joystick.h>
|
||||
#include <frc/PneumaticsControlModule.h>
|
||||
#include <frc/Solenoid.h>
|
||||
#include <frc/TimedRobot.h>
|
||||
|
||||
/**
|
||||
* This is a sample program showing the use of the solenoid classes during
|
||||
* operator control.
|
||||
*
|
||||
* Three buttons from a joystick will be used to control two solenoids: One
|
||||
* button to control the position of a single solenoid and the other two buttons
|
||||
* to control a double solenoid.
|
||||
*
|
||||
* Single solenoids can either be on or off, such that the air diverted through
|
||||
* them goes through either one channel or the other.
|
||||
*
|
||||
* Double solenoids have three states: Off, Forward, and Reverse. Forward and
|
||||
* Reverse divert the air through the two channels and correspond to the on and
|
||||
* off of a single solenoid, but a double solenoid can also be "off", where both
|
||||
* channels are diverted to exhaust such that there is no pressure in either
|
||||
* channel.
|
||||
*
|
||||
* Additionally, double solenoids take up two channels on your PCM whereas
|
||||
* single solenoids only take a single channel.
|
||||
*/
|
||||
|
||||
class Robot : public frc::TimedRobot {
|
||||
public:
|
||||
void RobotInit() override;
|
||||
void TeleopPeriodic() override;
|
||||
|
||||
private:
|
||||
frc::Joystick m_stick{0};
|
||||
|
||||
// Solenoid corresponds to a single solenoid.
|
||||
// In this case, it's connected to channel 0 of a PH with the default CAN
|
||||
// ID.
|
||||
frc::Solenoid m_solenoid{frc::PneumaticsModuleType::REVPH, 0};
|
||||
|
||||
// DoubleSolenoid corresponds to a double solenoid.
|
||||
// In this case, it's connected to channels 1 and 2 of a PH with the default
|
||||
// CAN ID.
|
||||
frc::DoubleSolenoid m_doubleSolenoid{frc::PneumaticsModuleType::REVPH, 1, 2};
|
||||
|
||||
// Compressor connected to a PH with a default CAN ID
|
||||
frc::Compressor m_compressor{frc::PneumaticsModuleType::REVPH};
|
||||
|
||||
static constexpr int kSolenoidButton = 1;
|
||||
static constexpr int kDoubleSolenoidForward = 2;
|
||||
static constexpr int kDoubleSolenoidReverse = 3;
|
||||
static constexpr int kCompressorButton = 4;
|
||||
};
|
||||
@@ -58,6 +58,7 @@
|
||||
"tags": [
|
||||
"Hardware",
|
||||
"Joystick",
|
||||
"Shuffleboard",
|
||||
"Pneumatics"
|
||||
],
|
||||
"foldername": "Solenoid",
|
||||
|
||||
Reference in New Issue
Block a user