[examples] Improve Pneumatics example coverage in Solenoid and RapidReactCmdBot examples (#4998)

This commit is contained in:
Starlight220
2023-07-04 07:23:18 +03:00
committed by GitHub
parent 6b5817836d
commit fffe6a7b9a
14 changed files with 393 additions and 73 deletions

View File

@@ -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() {

View File

@@ -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()};
}

View File

@@ -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{

View File

@@ -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]};
};

View File

@@ -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};
};

View File

@@ -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() {

View File

@@ -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;
};

View File

@@ -58,6 +58,7 @@
"tags": [
"Hardware",
"Joystick",
"Shuffleboard",
"Pneumatics"
],
"foldername": "Solenoid",