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