001 /*----------------------------------------------------------------------------*/
002 /* Copyright (c) FIRST 2008-2012. 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
008 package edu.wpi.first.wpilibj;
009
010 import edu.wpi.first.wpilibj.communication.UsageReporting;
011 import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
012 import edu.wpi.first.wpilibj.parsing.IDevice;
013 import edu.wpi.first.wpilibj.tables.ITable;
014
015 /**
016 * Compressor object.
017 * The Compressor object is designed to handle the operation of the compressor, pressure sensor and
018 * relay for a FIRST robot pneumatics system. The Compressor object starts a task which runs in the
019 * background and periodically polls the pressure sensor and operates the relay that controls the
020 * compressor.
021 */
022 public class Compressor extends SensorBase implements IDevice, LiveWindowSendable{
023
024 private DigitalInput m_pressureSwitch;
025 private Relay m_relay;
026 private boolean m_enabled;
027 private Thread m_task;
028 private boolean m_run = true;
029
030 /**
031 * Internal thread.
032 *
033 * Task which checks the compressor pressure switch and operates the relay as necessary
034 * depending on the pressure.
035 *
036 * Do not call this function directly.
037 */
038 private class CompressorThread extends Thread {
039
040 Compressor m_compressor;
041
042 CompressorThread(Compressor comp) {
043 m_compressor = comp;
044 }
045
046 public void run() {
047 while (m_run) {
048 if (m_compressor.enabled()) {
049 m_compressor.setRelayValue(!m_compressor.getPressureSwitchValue() ? Relay.Value.kOn : Relay.Value.kOff);
050 } else {
051 m_compressor.setRelayValue(Relay.Value.kOff);
052 }
053 try {
054 Thread.sleep(500);
055 } catch (InterruptedException e) {
056 }
057 }
058 }
059 }
060
061 /**
062 * Initialize the Compressor object.
063 * This method is the common initialization code for all the constructors for the Compressor
064 * object. It takes the relay channel and pressure switch channel and spawns a task that polls the
065 * compressor and sensor.
066 *
067 * You MUST start the compressor by calling the start() method.
068 */
069 private void initCompressor(final int pressureSwitchSlot,
070 final int pressureSwitchChannel,
071 final int compresssorRelaySlot,
072 final int compressorRelayChannel) {
073
074 m_enabled = false;
075 m_pressureSwitch = new DigitalInput(pressureSwitchSlot, pressureSwitchChannel);
076 m_relay = new Relay(compresssorRelaySlot, compressorRelayChannel, Relay.Direction.kForward);
077
078 UsageReporting.report(UsageReporting.kResourceType_Compressor, 0);
079
080 m_task = new CompressorThread(this);
081 m_task.start();
082 }
083
084 /**
085 * Compressor constructor.
086 * Given a fully specified relay channel and pressure switch channel, initialize the Compressor object.
087 *
088 * You MUST start the compressor by calling the start() method.
089 *
090 * @param pressureSwitchSlot The module that the pressure switch is attached to.
091 * @param pressureSwitchChannel The GPIO channel that the pressure switch is attached to.
092 * @param compresssorRelaySlot The module that the compressor relay is attached to.
093 * @param compressorRelayChannel The relay channel that the compressor relay is attached to.
094 */
095 public Compressor(final int pressureSwitchSlot,
096 final int pressureSwitchChannel,
097 final int compresssorRelaySlot,
098 final int compressorRelayChannel) {
099 initCompressor(pressureSwitchSlot,
100 pressureSwitchChannel,
101 compresssorRelaySlot,
102 compressorRelayChannel);
103 }
104
105 /**
106 * Compressor constructor.
107 * Given a relay channel and pressure switch channel (both in the default digital module), initialize
108 * the Compressor object.
109 *
110 * You MUST start the compressor by calling the start() method.
111 *
112 * @param pressureSwitchChannel The GPIO channel that the pressure switch is attached to.
113 * @param compressorRelayChannel The relay channel that the compressor relay is attached to.
114 */
115 public Compressor(final int pressureSwitchChannel, final int compressorRelayChannel) {
116 initCompressor(getDefaultDigitalModule(),
117 pressureSwitchChannel,
118 getDefaultDigitalModule(),
119 compressorRelayChannel);
120 }
121
122 /**
123 * Delete the Compressor object.
124 * Delete the allocated resources for the compressor and kill the compressor task that is polling
125 * the pressure switch.
126 */
127 public void free() {
128 m_run = false;
129 try { m_task.join(); }
130 catch (InterruptedException e) {}
131 m_pressureSwitch.free();
132 m_relay.free();
133 m_pressureSwitch = null;
134 m_relay = null;
135 }
136
137 /**
138 * Operate the relay for the compressor.
139 * Change the value of the relay output that is connected to the compressor motor.
140 * This is only intended to be called by the internal polling thread.
141 * @param relayValue the value to set the relay to
142 */
143 public void setRelayValue(Relay.Value relayValue) {
144 m_relay.set(relayValue);
145 }
146
147 /**
148 * Get the pressure switch value.
149 * Read the pressure switch digital input.
150 *
151 * @return The current state of the pressure switch.
152 */
153 public boolean getPressureSwitchValue() {
154 return m_pressureSwitch.get();
155 }
156
157 /**
158 * Start the compressor.
159 * This method will allow the polling loop to actually operate the compressor. The
160 * is stopped by default and won't operate until starting it.
161 */
162 public void start() {
163 m_enabled = true;
164 }
165
166 /**
167 * Stop the compressor.
168 * This method will stop the compressor from turning on.
169 */
170 public void stop() {
171 m_enabled = false;
172 }
173
174 /**
175 * Get the state of the enabled flag.
176 * Return the state of the enabled flag for the compressor and pressure switch
177 * combination.
178 *
179 * @return The state of the compressor thread's enable flag.
180 */
181 public boolean enabled() {
182 return m_enabled;
183 }
184
185 /*
186 * Live Window code, only does anything if live window is activated.
187 */
188 public String getSmartDashboardType(){
189 return "Compressor";
190 }
191 private ITable m_table;
192
193 /**
194 * {@inheritDoc}
195 */
196 public void initTable(ITable subtable) {
197 m_table = subtable;
198 updateTable();
199 }
200
201 /**
202 * {@inheritDoc}
203 */
204 public ITable getTable(){
205 return m_table;
206 }
207
208 /**
209 * {@inheritDoc}
210 */
211 public void updateTable() {
212 if (m_table != null) {
213 m_table.putBoolean("Enabled", m_enabled);
214 m_table.putBoolean("Pressure Switch", getPressureSwitchValue());
215 }
216 }
217
218 /**
219 * {@inheritDoc}
220 */
221 public void startLiveWindowMode() {}
222
223 /**
224 * {@inheritDoc}
225 */
226 public void stopLiveWindowMode() {}
227 }