001/*----------------------------------------------------------------------------*/ 002/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */ 003/* Open Source Software - may be modified and shared by FRC teams. The code */ 004/* must be accompanied by the FIRST BSD license file in the root directory of */ 005/* the project. */ 006/*----------------------------------------------------------------------------*/ 007 008package edu.wpi.first.wpilibj; 009 010import edu.wpi.first.wpilibj.hal.CompressorJNI; 011import edu.wpi.first.wpilibj.hal.FRCNetComm.tResourceType; 012import edu.wpi.first.wpilibj.hal.HAL; 013import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder; 014 015/** 016 * Class for operating a compressor connected to a PCM (Pneumatic Control Module). The PCM will 017 * automatically run in closed loop mode by default whenever a {@link Solenoid} object is created. 018 * For most cases, a Compressor object does not need to be instantiated or used in a robot program. 019 * This class is only required in cases where the robot program needs a more detailed status of the 020 * compressor or to enable/disable closed loop control. 021 * 022 * <p>Note: you cannot operate the compressor directly from this class as doing so would circumvent 023 * the safety provided by using the pressure switch and closed loop control. You can only turn off 024 * closed loop control, thereby stopping the compressor from operating. 025 */ 026public class Compressor extends SendableBase implements Sendable { 027 private int m_compressorHandle; 028 private byte m_module; 029 030 /** 031 * Makes a new instance of the compressor using the provided CAN device ID. Use this constructor 032 * when you have more than one PCM. 033 * 034 * @param module The PCM CAN device ID (0 - 62 inclusive) 035 */ 036 public Compressor(int module) { 037 m_module = (byte) module; 038 039 m_compressorHandle = CompressorJNI.initializeCompressor((byte) module); 040 041 HAL.report(tResourceType.kResourceType_Compressor, module); 042 setName("Compressor", module); 043 } 044 045 /** 046 * Makes a new instance of the compressor using the default PCM ID of 0. 047 * 048 * <p>Additional modules can be supported by making a new instance and {@link #Compressor(int) 049 * specifying the CAN ID.} 050 */ 051 public Compressor() { 052 this(SensorBase.getDefaultSolenoidModule()); 053 } 054 055 /** 056 * Start the compressor running in closed loop control mode. 057 * 058 * <p>Use the method in cases where you would like to manually stop and start the compressor for 059 * applications such as conserving battery or making sure that the compressor motor doesn't start 060 * during critical operations. 061 */ 062 public void start() { 063 setClosedLoopControl(true); 064 } 065 066 /** 067 * Stop the compressor from running in closed loop control mode. 068 * 069 * <p>Use the method in cases where you would like to manually stop and start the compressor for 070 * applications such as conserving battery or making sure that the compressor motor doesn't start 071 * during critical operations. 072 */ 073 public void stop() { 074 setClosedLoopControl(false); 075 } 076 077 /** 078 * Get the status of the compressor. 079 * 080 * @return true if the compressor is on 081 */ 082 public boolean enabled() { 083 return CompressorJNI.getCompressor(m_compressorHandle); 084 } 085 086 /** 087 * Get the pressure switch value. 088 * 089 * @return true if the pressure is low 090 */ 091 public boolean getPressureSwitchValue() { 092 return CompressorJNI.getCompressorPressureSwitch(m_compressorHandle); 093 } 094 095 /** 096 * Get the current being used by the compressor. 097 * 098 * @return current consumed by the compressor in amps 099 */ 100 public double getCompressorCurrent() { 101 return CompressorJNI.getCompressorCurrent(m_compressorHandle); 102 } 103 104 /** 105 * Set the PCM in closed loop control mode. 106 * 107 * @param on if true sets the compressor to be in closed loop control mode (default) 108 */ 109 public void setClosedLoopControl(boolean on) { 110 CompressorJNI.setCompressorClosedLoopControl(m_compressorHandle, on); 111 } 112 113 /** 114 * Gets the current operating mode of the PCM. 115 * 116 * @return true if compressor is operating on closed-loop mode 117 */ 118 public boolean getClosedLoopControl() { 119 return CompressorJNI.getCompressorClosedLoopControl(m_compressorHandle); 120 } 121 122 /** 123 * If PCM is in fault state : Compressor Drive is disabled due to compressor current being too 124 * high. 125 * 126 * @return true if PCM is in fault state. 127 */ 128 public boolean getCompressorCurrentTooHighFault() { 129 return CompressorJNI.getCompressorCurrentTooHighFault(m_compressorHandle); 130 } 131 132 /** 133 * If PCM sticky fault is set : Compressor is disabled due to compressor current being too 134 * high. 135 * 136 * @return true if PCM sticky fault is set. 137 */ 138 public boolean getCompressorCurrentTooHighStickyFault() { 139 return CompressorJNI.getCompressorCurrentTooHighStickyFault(m_compressorHandle); 140 } 141 142 /** 143 * If PCM sticky fault is set : Compressor output appears to be shorted. 144 * 145 * @return true if PCM sticky fault is set. 146 */ 147 public boolean getCompressorShortedStickyFault() { 148 return CompressorJNI.getCompressorShortedStickyFault(m_compressorHandle); 149 } 150 151 /** 152 * If PCM is in fault state : Compressor output appears to be shorted. 153 * 154 * @return true if PCM is in fault state. 155 */ 156 public boolean getCompressorShortedFault() { 157 return CompressorJNI.getCompressorShortedFault(m_compressorHandle); 158 } 159 160 /** 161 * If PCM sticky fault is set : Compressor does not appear to be wired, i.e. compressor is not 162 * drawing enough current. 163 * 164 * @return true if PCM sticky fault is set. 165 */ 166 public boolean getCompressorNotConnectedStickyFault() { 167 return CompressorJNI.getCompressorNotConnectedStickyFault(m_compressorHandle); 168 } 169 170 /** 171 * If PCM is in fault state : Compressor does not appear to be wired, i.e. compressor is not 172 * drawing enough current. 173 * 174 * @return true if PCM is in fault state. 175 */ 176 public boolean getCompressorNotConnectedFault() { 177 return CompressorJNI.getCompressorNotConnectedFault(m_compressorHandle); 178 } 179 180 /** 181 * Clear ALL sticky faults inside PCM that Compressor is wired to. 182 * 183 * <p>If a sticky fault is set, then it will be persistently cleared. The compressor might 184 * momentarily disable while the flags are being cleared. Doo not call this method too 185 * frequently, otherwise normal compressor functionality may be prevented. 186 * 187 * <p>If no sticky faults are set then this call will have no effect. 188 */ 189 public void clearAllPCMStickyFaults() { 190 CompressorJNI.clearAllPCMStickyFaults(m_module); 191 } 192 193 @Override 194 public void initSendable(SendableBuilder builder) { 195 builder.setSmartDashboardType("Compressor"); 196 builder.addBooleanProperty("Enabled", this::enabled, (value) -> { 197 if (value) { 198 start(); 199 } else { 200 stop(); 201 } 202 }); 203 builder.addBooleanProperty("Pressure switch", this::getPressureSwitchValue, null); 204 } 205}