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.wpilibj; 006 007import edu.wpi.first.hal.FRCNetComm.tResourceType; 008import edu.wpi.first.hal.HAL; 009import edu.wpi.first.hal.util.AllocationException; 010import edu.wpi.first.util.sendable.Sendable; 011import edu.wpi.first.util.sendable.SendableBuilder; 012import edu.wpi.first.util.sendable.SendableRegistry; 013 014/** 015 * Class for operating a compressor connected to a pneumatics module. The module will automatically 016 * run in closed loop mode by default whenever a {@link Solenoid} object is created. For most cases, 017 * a Compressor object does not need to be instantiated or used in a robot program. This class is 018 * only required in cases where the robot program needs a more detailed status of the compressor or 019 * to enable/disable closed loop control. 020 * 021 * <p>Note: you cannot operate the compressor directly from this class as doing so would circumvent 022 * the safety provided by using the pressure switch and closed loop control. You can only turn off 023 * closed loop control, thereby stopping the compressor from operating. 024 */ 025public class Compressor implements Sendable, AutoCloseable { 026 private PneumaticsBase m_module; 027 028 /** 029 * Constructs a compressor for a specified module and type. 030 * 031 * @param module The module ID to use. 032 * @param moduleType The module type to use. 033 */ 034 public Compressor(int module, PneumaticsModuleType moduleType) { 035 m_module = PneumaticsBase.getForType(module, moduleType); 036 037 if (!m_module.reserveCompressor()) { 038 m_module.close(); 039 throw new AllocationException("Compressor already allocated"); 040 } 041 042 m_module.enableCompressorDigital(); 043 044 HAL.report(tResourceType.kResourceType_Compressor, module + 1); 045 SendableRegistry.addLW(this, "Compressor", module); 046 } 047 048 /** 049 * Constructs a compressor for a default module and specified type. 050 * 051 * @param moduleType The module type to use. 052 */ 053 public Compressor(PneumaticsModuleType moduleType) { 054 this(PneumaticsBase.getDefaultForType(moduleType), moduleType); 055 } 056 057 @Override 058 public void close() { 059 SendableRegistry.remove(this); 060 m_module.unreserveCompressor(); 061 m_module.close(); 062 m_module = null; 063 } 064 065 /** 066 * Get the status of the compressor. To (re)enable the compressor use enableDigital() or 067 * enableAnalog(...). 068 * 069 * @return true if the compressor is on 070 * @deprecated To avoid confusion in thinking this (re)enables the compressor use IsEnabled(). 071 */ 072 @Deprecated(since = "2023", forRemoval = true) 073 public boolean enabled() { 074 return isEnabled(); 075 } 076 077 /** 078 * Returns whether the compressor is active or not. 079 * 080 * @return true if the compressor is on - otherwise false. 081 */ 082 public boolean isEnabled() { 083 return m_module.getCompressor(); 084 } 085 086 /** 087 * Returns the state of the pressure switch. 088 * 089 * @return True if pressure switch indicates that the system is not full, otherwise false. 090 */ 091 public boolean getPressureSwitchValue() { 092 return m_module.getPressureSwitch(); 093 } 094 095 /** 096 * Get the current drawn by the compressor. 097 * 098 * @return Current drawn by the compressor in amps. 099 */ 100 public double getCurrent() { 101 return m_module.getCompressorCurrent(); 102 } 103 104 /** 105 * If supported by the device, returns the analog input voltage (on channel 0). 106 * 107 * <p>This function is only supported by the REV PH. On CTRE PCM, this will return 0. 108 * 109 * @return The analog input voltage, in volts. 110 */ 111 public double getAnalogVoltage() { 112 return m_module.getAnalogVoltage(0); 113 } 114 115 /** 116 * If supported by the device, returns the pressure (in PSI) read by the analog pressure sensor 117 * (on channel 0). 118 * 119 * <p>This function is only supported by the REV PH with the REV Analog Pressure Sensor. On CTRE 120 * PCM, this will return 0. 121 * 122 * @return The pressure (in PSI) read by the analog pressure sensor. 123 */ 124 public double getPressure() { 125 return m_module.getPressure(0); 126 } 127 128 /** Disable the compressor. */ 129 public void disable() { 130 m_module.disableCompressor(); 131 } 132 133 /** 134 * Enables the compressor in digital mode using the digital pressure switch. The compressor will 135 * turn on when the pressure switch indicates that the system is not full, and will turn off when 136 * the pressure switch indicates that the system is full. 137 */ 138 public void enableDigital() { 139 m_module.enableCompressorDigital(); 140 } 141 142 /** 143 * If supported by the device, enables the compressor in analog mode. This mode uses an analog 144 * pressure sensor connected to analog channel 0 to cycle the compressor. The compressor will turn 145 * on when the pressure drops below {@code minPressure} and will turn off when the pressure 146 * reaches {@code maxPressure}. This mode is only supported by the REV PH with the REV Analog 147 * Pressure Sensor connected to analog channel 0. 148 * 149 * <p>On CTRE PCM, this will enable digital control. 150 * 151 * @param minPressure The minimum pressure in PSI. The compressor will turn on when the pressure 152 * drops below this value. 153 * @param maxPressure The maximum pressure in PSI. The compressor will turn off when the pressure 154 * reaches this value. 155 */ 156 public void enableAnalog(double minPressure, double maxPressure) { 157 m_module.enableCompressorAnalog(minPressure, maxPressure); 158 } 159 160 /** 161 * If supported by the device, enables the compressor in hybrid mode. This mode uses both a 162 * digital pressure switch and an analog pressure sensor connected to analog channel 0 to cycle 163 * the compressor. This mode is only supported by the REV PH with the REV Analog Pressure Sensor 164 * connected to analog channel 0. 165 * 166 * <p>The compressor will turn on when <i>both</i>: 167 * 168 * <ul> 169 * <li>The digital pressure switch indicates the system is not full AND 170 * <li>The analog pressure sensor indicates that the pressure in the system is below the 171 * specified minimum pressure. 172 * </ul> 173 * 174 * <p>The compressor will turn off when <i>either</i>: 175 * 176 * <ul> 177 * <li>The digital pressure switch is disconnected or indicates that the system is full OR 178 * <li>The pressure detected by the analog sensor is greater than the specified maximum 179 * pressure. 180 * </ul> 181 * 182 * <p>On CTRE PCM, this will enable digital control. 183 * 184 * @param minPressure The minimum pressure in PSI. The compressor will turn on when the pressure 185 * drops below this value and the pressure switch indicates that the system is not full. 186 * @param maxPressure The maximum pressure in PSI. The compressor will turn off when the pressure 187 * reaches this value or the pressure switch is disconnected or indicates that the system is 188 * full. 189 */ 190 public void enableHybrid(double minPressure, double maxPressure) { 191 m_module.enableCompressorHybrid(minPressure, maxPressure); 192 } 193 194 /** 195 * Returns the active compressor configuration. 196 * 197 * @return The active compressor configuration. 198 */ 199 public CompressorConfigType getConfigType() { 200 return m_module.getCompressorConfigType(); 201 } 202 203 @Override 204 public void initSendable(SendableBuilder builder) { 205 builder.setSmartDashboardType("Compressor"); 206 builder.addBooleanProperty("Enabled", this::isEnabled, null); 207 builder.addBooleanProperty("Pressure switch", this::getPressureSwitchValue, null); 208 } 209}