diff --git a/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/DoubleSolenoid.java b/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/DoubleSolenoid.java index b64a9e7b6b..f0b155d080 100644 --- a/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/DoubleSolenoid.java +++ b/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/DoubleSolenoid.java @@ -50,28 +50,28 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable { * Common function to implement constructor behavior. */ private synchronized void initSolenoid() { -// checkSolenoidModule(m_moduleNumber); -// checkSolenoidChannel(m_forwardChannel); -// checkSolenoidChannel(m_reverseChannel); -// -// try { -// m_allocated.allocate((m_moduleNumber - 1) * kSolenoidChannels + m_forwardChannel - 1); -// } catch (CheckedAllocationException e) { -// throw new AllocationException( -// "Solenoid channel " + m_forwardChannel + " on module " + m_moduleNumber + " is already allocated"); -// } -// try { -// m_allocated.allocate((m_moduleNumber - 1) * kSolenoidChannels + m_reverseChannel - 1); -// } catch (CheckedAllocationException e) { -// throw new AllocationException( -// "Solenoid channel " + m_reverseChannel + " on module " + m_moduleNumber + " is already allocated"); -// } -// m_forwardMask = (byte) (1 << (m_forwardChannel - 1)); -// m_reverseMask = (byte) (1 << (m_reverseChannel - 1)); -// -// UsageReporting.report(tResourceType.kResourceType_Solenoid, m_forwardChannel, m_moduleNumber-1); -// UsageReporting.report(tResourceType.kResourceType_Solenoid, m_reverseChannel, m_moduleNumber-1); -// LiveWindow.addActuator("DoubleSolenoid", m_moduleNumber, m_forwardChannel, this); + checkSolenoidModule(m_moduleNumber); + checkSolenoidChannel(m_forwardChannel); + checkSolenoidChannel(m_reverseChannel); + + try { + m_allocated.allocate(m_moduleNumber * kSolenoidChannels + m_forwardChannel); + } catch (CheckedAllocationException e) { + throw new AllocationException( + "Solenoid channel " + m_forwardChannel + " on module " + m_moduleNumber + " is already allocated"); + } + try { + m_allocated.allocate(m_moduleNumber * kSolenoidChannels + m_reverseChannel); + } catch (CheckedAllocationException e) { + throw new AllocationException( + "Solenoid channel " + m_reverseChannel + " on module " + m_moduleNumber + " is already allocated"); + } + m_forwardMask = (byte) (1 << m_forwardChannel); + m_reverseMask = (byte) (1 << m_reverseChannel); + + UsageReporting.report(tResourceType.kResourceType_Solenoid, m_forwardChannel, m_moduleNumber); + UsageReporting.report(tResourceType.kResourceType_Solenoid, m_reverseChannel, m_moduleNumber); + LiveWindow.addActuator("DoubleSolenoid", m_moduleNumber, m_forwardChannel, this); } /** @@ -105,8 +105,8 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable { * Destructor. */ public synchronized void free() { -// m_allocated.free((m_moduleNumber - 1) * kSolenoidChannels + m_forwardChannel - 1); -// m_allocated.free((m_moduleNumber - 1) * kSolenoidChannels + m_reverseChannel - 1); + m_allocated.free(m_moduleNumber * kSolenoidChannels + m_forwardChannel); + m_allocated.free(m_moduleNumber * kSolenoidChannels + m_reverseChannel); } /** diff --git a/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/Solenoid.java b/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/Solenoid.java index 07d666ff16..ddd6199d56 100644 --- a/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/Solenoid.java +++ b/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/Solenoid.java @@ -86,10 +86,10 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable { * @param on Turn the solenoid output off or on. */ public void set(boolean on) { - ByteBuffer status = ByteBuffer.allocateDirect(4); - status.order(ByteOrder.LITTLE_ENDIAN); - SolenoidJNI.setSolenoid(m_solenoid_port, (byte) (on ? 1 : 0), status.asIntBuffer()); - HALUtil.checkStatus(status.asIntBuffer()); + byte value = (byte) (on ? 0xFF : 0x00); + byte mask = (byte) (1 << m_channel); + + set(value, mask); } /** @@ -98,11 +98,8 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable { * @return The current value of the solenoid. */ public boolean get() { - ByteBuffer status = ByteBuffer.allocateDirect(4); - status.order(ByteOrder.LITTLE_ENDIAN); - boolean value = SolenoidJNI.getSolenoid(m_solenoid_port, status.asIntBuffer()) != 0; - HALUtil.checkStatus(status.asIntBuffer()); - return value; + int value = getAll() & ( 1 << m_channel); + return (value != 0); } /* diff --git a/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/SolenoidBase.java b/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/SolenoidBase.java index a7c0284cec..fbc68de79f 100644 --- a/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/SolenoidBase.java +++ b/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/SolenoidBase.java @@ -11,6 +11,7 @@ import java.nio.IntBuffer; import java.nio.ByteBuffer; import edu.wpi.first.wpilibj.hal.HALUtil; +import edu.wpi.first.wpilibj.hal.SolenoidJNI; /** * SolenoidBase class is the common base class for the Solenoid and @@ -20,8 +21,7 @@ public abstract class SolenoidBase extends SensorBase { private ByteBuffer[] m_ports; protected int m_moduleNumber; ///< The number of the solenoid module being used. - // XXX: Move this to be both HAL calls - //protected Resource m_allocated = new Resource(SolenoidJNI.getModuleCount() * SensorBase.kSolenoidChannels); + protected Resource m_allocated = new Resource(63* SensorBase.kSolenoidChannels); /** * Constructor. @@ -30,13 +30,13 @@ public abstract class SolenoidBase extends SensorBase { */ public SolenoidBase(final int moduleNumber) { m_moduleNumber = moduleNumber; -// m_ports = new ByteBuffer[SensorBase.kSolenoidChannels]; -// for (int i = 0; i < SensorBase.kSolenoidChannels; i++) { -// ByteBuffer port = SolenoidJNI.getPortWithModule((byte) moduleNumber, (byte) (i+1)); -// IntBuffer status = IntBuffer.allocate(1); -// m_ports[i] = SolenoidJNI.initializeSolenoidPort(port, status); -// HALUtil.checkStatus(status); -// } + m_ports = new ByteBuffer[SensorBase.kSolenoidChannels]; + for (int i = 0; i < SensorBase.kSolenoidChannels; i++) { + ByteBuffer port = SolenoidJNI.getPortWithModule((byte) moduleNumber, (byte) i); + IntBuffer status = IntBuffer.allocate(1); + m_ports[i] = SolenoidJNI.initializeSolenoidPort(port, status); + HALUtil.checkStatus(status); + } } /** @@ -46,13 +46,13 @@ public abstract class SolenoidBase extends SensorBase { * @param mask The channels you want to be affected. */ protected synchronized void set(int value, int mask) { -// IntBuffer status = IntBuffer.allocate(1); -// for (int i = 0; i < SensorBase.kSolenoidChannels; i++) { -// int local_mask = 1 << i; -// if ((mask & local_mask) != 0) -// SolenoidJNI.setSolenoid(m_ports[i], (byte) (value & local_mask), status); -// } -// HALUtil.checkStatus(status); + IntBuffer status = IntBuffer.allocate(1); + for (int i = 0; i < SensorBase.kSolenoidChannels; i++) { + int local_mask = 1 << i; + if ((mask & local_mask) != 0) + SolenoidJNI.setSolenoid(m_ports[i], (byte) (value & local_mask), status); + } + HALUtil.checkStatus(status); } /** @@ -62,32 +62,11 @@ public abstract class SolenoidBase extends SensorBase { */ public byte getAll() { byte value = 0; -// IntBuffer status = IntBuffer.allocate(1); -// for (int i = 0; i < SensorBase.kSolenoidChannels; i++) { -// value |= SolenoidJNI.getSolenoid(m_ports[i], status) << i; -// } -// HALUtil.checkStatus(status); + IntBuffer status = IntBuffer.allocate(1); + for (int i = 0; i < SensorBase.kSolenoidChannels; i++) { + value |= SolenoidJNI.getSolenoid(m_ports[i], status) << i; + } + HALUtil.checkStatus(status); return value; } - - /** - * Read all 8 solenoids in the default solenoid module as a single byte - * - * @return The current value of all 8 solenoids on the default module. - */ - public static byte getAllFromDefaultModule() { - return getAllFromModule(getDefaultSolenoidModule()); - } - - /** - * Read all 8 solenoids in the specified solenoid module as a single byte - * - * @return The current value of all 8 solenoids on the specified module. - */ - public static byte getAllFromModule(int moduleNumber) { - byte value = 0; -// checkSolenoidModule(moduleNumber); -// throw new RuntimeException("Not supported right now."); - return value; - } } diff --git a/wpilibj/wpilibJavaIntegrationTests/src/main/java/edu/wpi/first/wpilibj/PCMTest.java b/wpilibj/wpilibJavaIntegrationTests/src/main/java/edu/wpi/first/wpilibj/PCMTest.java index c84bfd6d78..d70cc4627b 100644 --- a/wpilibj/wpilibJavaIntegrationTests/src/main/java/edu/wpi/first/wpilibj/PCMTest.java +++ b/wpilibj/wpilibJavaIntegrationTests/src/main/java/edu/wpi/first/wpilibj/PCMTest.java @@ -32,7 +32,7 @@ public class PCMTest extends AbstractComsSetup { protected static final double kCompressorDelayTime = 2.0; /* Solenoids should change much more quickly */ - protected static final double kSolenoidDelayTime = 0.1; + protected static final double kSolenoidDelayTime = 1.0; /* The voltage divider on the test bench should bring the compressor output to around these values. */ @@ -44,7 +44,6 @@ public class PCMTest extends AbstractComsSetup { private static DigitalOutput fakePressureSwitch; private static AnalogInput fakeCompressor; - private static Solenoid solenoid1, solenoid2; private static DigitalInput fakeSolenoid1, fakeSolenoid2; @BeforeClass @@ -54,9 +53,6 @@ public class PCMTest extends AbstractComsSetup { fakePressureSwitch = new DigitalOutput(11); fakeCompressor = new AnalogInput(1); - solenoid1 = new Solenoid(7); - solenoid2 = new Solenoid(6); - fakeSolenoid1 = new DigitalInput(12); fakeSolenoid2 = new DigitalInput(13); } @@ -68,9 +64,6 @@ public class PCMTest extends AbstractComsSetup { fakePressureSwitch.free(); fakeCompressor.free(); - solenoid1.free(); - solenoid2.free(); - fakeSolenoid1.free(); fakeSolenoid2.free(); } @@ -83,8 +76,6 @@ public class PCMTest extends AbstractComsSetup { public void reset() throws Exception { compressor.stop(); fakePressureSwitch.set(false); - solenoid1.set(false); - solenoid2.set(false); } @After @@ -120,6 +111,9 @@ public class PCMTest extends AbstractComsSetup { public void testSolenoid() throws Exception { reset(); + Solenoid solenoid1 = new Solenoid(0); + Solenoid solenoid2 = new Solenoid(1); + solenoid1.set(false); solenoid2.set(false); Timer.delay(kSolenoidDelayTime); @@ -146,6 +140,35 @@ public class PCMTest extends AbstractComsSetup { Timer.delay(kSolenoidDelayTime); assertFalse("Solenoid #1 did not turn on",fakeSolenoid1.get()); assertFalse("Solenoid #2 did not turn on",fakeSolenoid2.get()); + + solenoid1.free(); + solenoid2.free(); + } + + /** + * Test if the correct solenoids turn on and off when they should when used + * with the DoubleSolenoid class. + */ + @Test + public void doubleSolenoid() { + DoubleSolenoid solenoid = new DoubleSolenoid(0, 1); + + solenoid.set(DoubleSolenoid.Value.kOff); + Timer.delay(kSolenoidDelayTime); + assertTrue("Solenoid #1 did not turn off", fakeSolenoid1.get()); + assertTrue("Solenoid #2 did not turn off", fakeSolenoid2.get()); + + solenoid.set(DoubleSolenoid.Value.kForward); + Timer.delay(kSolenoidDelayTime); + assertFalse("Solenoid #1 did not turn on", fakeSolenoid1.get()); + assertTrue("Solenoid #2 did not turn off", fakeSolenoid2.get()); + + solenoid.set(DoubleSolenoid.Value.kReverse); + Timer.delay(kSolenoidDelayTime); + assertTrue("Solenoid #1 did not turn off", fakeSolenoid1.get()); + assertFalse("Solenoid #2 did not turn on", fakeSolenoid2.get()); + + solenoid.free(); } protected Logger getClassLogger(){