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 }