WPILib Reorganization

This is a major restructuring of the WPILib repository to simply build
procedures and remove the remnants of Maven from everything except the
eclipse plugins. Gradle files have been largely simplified or rewritten,
taking advantage of splitting up parts of the build into separate build
files for ease of reading.

The eclipse plugins are now in a separate project, as is ntcore. All
dependencies are resolved via Maven dependencies, with the
Jenkins-maintained WPILib repo. Project structures have also been
simplified: we no longer have separate subprojects inside wpilibc and
wpilibj. Where possible, these changes hav been done with git renames,
to make sure we still have full history for all repositories. Other
unrelated subprojects have also been broken out: OutlineViewer is now a
separate project.

Change-Id: Ib4e2a6e1a2f66427a14f16612b0e0d69ed661878
This commit is contained in:
Fredric Silberberg
2015-09-24 20:26:49 -04:00
parent c20d34c2b6
commit 6d854afb0e
1769 changed files with 2278 additions and 333177 deletions

View File

@@ -0,0 +1,108 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008-2014. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.can;
import org.junit.After;
import org.junit.Before;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.fixtures.CANMotorEncoderFixture;
import edu.wpi.first.wpilibj.test.AbstractComsSetup;
import edu.wpi.first.wpilibj.test.TestBench;
/**
* Provides a base implementation for CAN Tests that forces a test of a
* particular mode to provide tests of a certain type. This also allows for a
* standardized base setup for each test.
*$
* @author jonathanleitschuh
*
*/
public abstract class AbstractCANTest extends AbstractComsSetup {
public static final double kMotorStopTime = 2;
public static final double kMotorTime = 3;
public static final double kMotorTimeSettling = 10;
public static final double kPotentiometerSettlingTime = 10.0;
public static final double kEncoderSettlingTime = 0.50;
public static final double kEncoderSpeedTolerance = 20.0;
public static final double kLimitSettlingTime = 20.0; // timeout in seconds
public static final double kStartupTime = 0.50;
public static final double kEncoderPositionTolerance = .75;
public static final double kPotentiometerPositionTolerance = 10.0 / 360.0; // +/-10
// degrees
public static final double kCurrentTolerance = 0.1;
/**
* Stores the status value for the previous test. This is set immediately
* after a failure or success and before the me is torn down.
*/
private String status = "";
/**
* Extends the default test watcher in order to provide more information about
* a tests failure at runtime.
*$
* @author jonathanleitschuh
*
*/
public class CANTestWatcher extends DefaultTestWatcher {
@Override
protected void failed(Throwable e, Description description) {
super.failed(e, description, status);
}
}
@Override
protected TestWatcher getOverridenTestWatcher() {
return new CANTestWatcher();
}
/** The Fixture under test */
private CANMotorEncoderFixture me;
/**
* Retrieves the CANMotorEncoderFixture
*$
* @return the CANMotorEncoderFixture for this test.
*/
public CANMotorEncoderFixture getME() {
return me;
}
/**
* This runs BEFORE the setup of the inherited class
*/
@Before
public final void preSetup() {
status = "";
me = TestBench.getInstance().getCanJaguarPair();
me.setup();
me.getMotor().setSafetyEnabled(false);
}
@After
public final void tearDown() throws Exception {
try {
// Stores the status data before tearing it down.
// If the test fails unexpectedly then this could cause an exception.
status = me.printStatus();
} finally {
me.teardown();
}
me = null;
}
protected void setCANJaguar(double seconds, double value) {
for (int i = 0; i < 50; i++) {
getME().getMotor().set(value);
Timer.delay(seconds / 50.0);
}
}
}

View File

@@ -0,0 +1,107 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008-2014. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.can;
import static org.junit.Assert.assertEquals;
import java.util.logging.Logger;
import org.junit.Before;
import org.junit.Test;
import org.junit.Ignore;
import edu.wpi.first.wpilibj.CANJaguar;
import edu.wpi.first.wpilibj.Timer;
/**
* @author jonathanleitschuh
*
*/
public class CANCurrentQuadEncoderModeTest extends AbstractCANTest {
private static Logger logger = Logger.getLogger(CANCurrentQuadEncoderModeTest.class.getName());
private static final double kStoppedValue = 0;
private static final double kRunningValue = 3.0;
/*
* (non-Javadoc)
*$
* @see edu.wpi.first.wpilibj.can.AbstractCANTest#stopMotor()
*/
protected void stopMotor() {
getME().getMotor().set(kStoppedValue);
}
/*
* (non-Javadoc)
*$
* @see edu.wpi.first.wpilibj.can.AbstractCANTest#runMotorForward()
*/
protected void runMotorForward() {
getME().getMotor().set(kRunningValue);
}
/*
* (non-Javadoc)
*$
* @see edu.wpi.first.wpilibj.can.AbstractCANTest#runMotorReverse()
*/
protected void runMotorReverse() {
getME().getMotor().set(-kRunningValue);
}
@Override
protected Logger getClassLogger() {
return logger;
}
@Before
public void setUp() throws Exception {
getME().getMotor().setCurrentMode(CANJaguar.kQuadEncoder, 360, 10.0, 4.0, 1.0);
getME().getMotor().enableControl();
getME().getMotor().set(0.0f);
/* The motor might still have momentum from the previous test. */
Timer.delay(kStartupTime);
}
@Ignore
@Test
public void testDriveToCurrentPositive() {
double setpoint = 1.6f;
/* It should get to the setpoint within 10 seconds */
for (int i = 0; i < 10; i++) {
setCANJaguar(1.0, setpoint);
if (Math.abs(getME().getMotor().getOutputCurrent() - setpoint) <= kCurrentTolerance) {
break;
}
}
assertEquals("The desired output current was not reached", setpoint, getME().getMotor()
.getOutputCurrent(), kCurrentTolerance);
}
@Ignore
@Test
public void testDriveToCurrentNegative() {
double setpoint = -1.6f;
/* It should get to the setpoint within 10 seconds */
for (int i = 0; i < 10; i++) {
setCANJaguar(1.0, setpoint);
if (Math.abs(getME().getMotor().getOutputCurrent() - Math.abs(setpoint)) <= kCurrentTolerance) {
break;
}
}
assertEquals("The desired output current was not reached", Math.abs(setpoint), getME()
.getMotor().getOutputCurrent(), kCurrentTolerance);
}
}

View File

@@ -0,0 +1,233 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008-2014. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.can;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import org.junit.Before;
import org.junit.Test;
import com.googlecode.junittoolbox.PollingWait;
import com.googlecode.junittoolbox.RunnableAssert;
import edu.wpi.first.wpilibj.CANJaguar;
import edu.wpi.first.wpilibj.Timer;
/**
* @author jonathanleitschuh
*
*/
public class CANDefaultTest extends AbstractCANTest {
private static final Logger logger = Logger.getLogger(CANDefaultTest.class.getName());
private final PollingWait wait = new PollingWait().timeoutAfter(65, TimeUnit.MILLISECONDS)
.pollEvery(10, TimeUnit.MILLISECONDS);
private static final double kSpikeTime = .5;
@Override
protected Logger getClassLogger() {
return logger;
}
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
getME().getMotor().enableControl();
getME().getMotor().set(0.0f);
/* The motor might still have momentum from the previous test. */
Timer.delay(kStartupTime / 2);
}
@Test
public void testDefaultGet() {
wait.until(new RunnableAssert("Waiting for CAN Jaguar get to return 0") {
@Override
public void run() {
assertEquals("CAN Jaguar did not initialize stopped", 0.0, getME().getMotor().get(), .01f);
}
});
}
@Test
public void testDefaultBusVoltage() {
wait.until(new RunnableAssert("Waiting for default bus voltage to be correct") {
@Override
public void run() {
assertEquals("CAN Jaguar did not start at 14 volts", 14.0f, getME().getMotor()
.getBusVoltage(), 2.0f);
}
});
}
@Test
public void testDefaultOutputVoltage() {
wait.until(new RunnableAssert("Waiting for output voltage to be correct") {
@Override
public void run() {
assertEquals("CAN Jaguar did not start with an output voltage of 0", 0.0f, getME()
.getMotor().getOutputVoltage(), 0.3f);
}
});
}
@Test
public void testDefaultOutputCurrent() {
wait.until(new RunnableAssert("Waiting for output current to be correct") {
@Override
public void run() {
assertEquals("CAN Jaguar did not start with an output current of 0", 0.0f, getME()
.getMotor().getOutputCurrent(), 0.3f);
}
});
}
@Test
public void testDefaultTemperature() {
final double room_temp = 18.0f;
wait.until(new RunnableAssert("Waiting for temperature to be correct") {
@Override
public void run() {
assertThat(
"CAN Jaguar did not start with an initial temperature greater than " + room_temp,
getME().getMotor().getTemperature(), is(greaterThan(room_temp)));
}
});
}
@Test
public void testDefaultForwardLimit() {
getME().getMotor().configLimitMode(CANJaguar.LimitMode.SwitchInputsOnly);
wait.until(new RunnableAssert("Waiting for forward limit to not be set") {
@Override
public void run() {
getME().getMotor().set(0);
assertTrue("CAN Jaguar did not start with the Forward Limit Switch Off", getME().getMotor()
.getForwardLimitOK());
}
});
}
@Test
public void testDefaultReverseLimit() {
getME().getMotor().configLimitMode(CANJaguar.LimitMode.SwitchInputsOnly);
wait.until(new RunnableAssert("Waiting for reverse limit to not be set") {
@Override
public void run() {
getME().getMotor().set(0);
assertTrue("CAN Jaguar did not start with the Reverse Limit Switch Off", getME().getMotor()
.getReverseLimitOK());
}
});
}
@Test
public void testDefaultNoFaults() {
wait.until(new RunnableAssert("Waiting for no faults") {
@Override
public void run() {
assertEquals("CAN Jaguar initialized with Faults", 0, getME().getMotor().getFaults());
}
});
}
@Test
public void testFakeLimitSwitchForwards() {
// Given
getME().getMotor().configLimitMode(CANJaguar.LimitMode.SwitchInputsOnly);
getME().getMotor().enableControl();
// When
getME().getForwardLimit().set(true);
// Then
PollingWait wait =
new PollingWait().timeoutAfter((long) kLimitSettlingTime, TimeUnit.SECONDS).pollEvery(1,
TimeUnit.MILLISECONDS);
wait.until(new RunnableAssert("Setting the CANJAguar forward limit switch high") {
@Override
public void run() throws Exception {
getME().getMotor().set(0);
assertFalse(
"Setting the forward limit switch high did not cause the forward limit switch to trigger",
getME().getMotor().getForwardLimitOK());
}
});
}
@Test
public void testFakeLimitSwitchReverse() {
// Given
getME().getMotor().configLimitMode(CANJaguar.LimitMode.SwitchInputsOnly);
getME().getMotor().enableControl();
// When
getME().getReverseLimit().set(true);
// Then
PollingWait wait =
new PollingWait().timeoutAfter((long) kLimitSettlingTime, TimeUnit.SECONDS).pollEvery(1,
TimeUnit.MILLISECONDS);
wait.until(new RunnableAssert("Setting the CANJAguar reverse limit switch high") {
@Override
public void run() throws Exception {
getME().getMotor().set(0);
assertFalse(
"Setting the reverse limit switch high did not cause the forward limit switch to trigger",
getME().getMotor().getReverseLimitOK());
}
});
}
@Test
public void testPositionModeVerifiesOnBrownOut() {
final double setpoint = 1.0;
// Given
getME().getMotor().setPositionMode(CANJaguar.kQuadEncoder, 360, 10.0, 0.1, 0.0);
getME().getMotor().enableControl();
setCANJaguar(kMotorTime, 0.0);
getME().powerOn();
// When
/* Turn the spike off and on again */
getME().powerOff();
Timer.delay(kSpikeTime);
getME().powerOn();
Timer.delay(kSpikeTime);
PollingWait wait =
new PollingWait().timeoutAfter(15, TimeUnit.SECONDS).pollEvery(1, TimeUnit.MILLISECONDS);
/*
* The jaguar should automatically get set to quad encoder position mode, so
* it should be able to reach a setpoint in a couple seconds.
*/
wait.until(new RunnableAssert("Waiting for CANJaguar to reach set-point") {
@Override
public void run() throws Exception {
getME().getMotor().set(setpoint);
assertEquals("CANJaguar should have resumed PID control after power cycle", setpoint,
getME().getMotor().getPosition(), kEncoderPositionTolerance);
}
});
}
}

View File

@@ -0,0 +1,78 @@
package edu.wpi.first.wpilibj.can;
import edu.wpi.first.wpilibj.CANJaguar;
import edu.wpi.first.wpilibj.Timer;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
import java.util.logging.Logger;
/**
* Created by Patrick Murphy on 3/30/15.
*/
public class CANJaguarInversionTest extends AbstractCANTest {
private static final Logger logger = Logger.getLogger(CANJaguarInversionTest.class.getName());
private static final double motorVoltage = 5.0;
private static final double motorPercent = 0.5;
private static final double motorSpeed = 100;
private static final double delayTime = 0.75;
private static final double speedModeDelayTime = 2.0;
@Override
protected Logger getClassLogger() {
return logger;
}
@Test
public void testInvertingVoltageMode() {
getME().getMotor().setVoltageMode(CANJaguar.kQuadEncoder, 360);
InversionTest(motorVoltage, delayTime);
}
@Test
public void testInvertingPercentMode() {
getME().getMotor().setPercentMode(CANJaguar.kQuadEncoder, 360);
InversionTest(motorPercent, delayTime);
}
@Test
public void testInvertingSpeedMode() {
getME().getMotor().setSpeedMode(CANJaguar.kQuadEncoder, 360, 0.1, 0.003, 0.01);
InversionTest(motorSpeed, speedModeDelayTime);
}
/**
* Runs an inversion test To use set the jaguar to the proper
* mode(PercentVbus, voltage, speed)
*$
* @param setpoint the speed/voltage/percent to set the motor to
* @param delayTime the amount of time to delay between starting a motor and
* checking the encoder
*/
private void InversionTest(double setpoint, double delayTime) {
CANJaguar jag = this.getME().getMotor();
jag.enableControl();
jag.setInverted(false);
jag.set(setpoint);
Timer.delay(delayTime);
double initialSpeed = jag.getSpeed();
jag.set(0.0);
jag.setInverted(true);
jag.set(setpoint);
Timer.delay(delayTime);
jag.set(0.0);
double finalSpeed = jag.getSpeed();
assertTrue("Inverting with Positive value does not invert direction",
Math.signum(initialSpeed) != Math.signum(finalSpeed));
jag.set(-setpoint);
Timer.delay(delayTime);
initialSpeed = jag.getSpeed();
jag.set(0.0);
jag.setInverted(false);
jag.set(-setpoint);
Timer.delay(delayTime);
finalSpeed = jag.getSpeed();
jag.set(0.0);
assertTrue("Inverting with Negative value does not invert direction",
Math.signum(initialSpeed) != Math.signum(finalSpeed));
}
}

View File

@@ -0,0 +1,399 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008-2014. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.can;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.lessThan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import com.googlecode.junittoolbox.PollingWait;
import com.googlecode.junittoolbox.RunnableAssert;
import edu.wpi.first.wpilibj.CANJaguar;
import edu.wpi.first.wpilibj.Timer;
/**
* @author jonathanleitschuh
*
*/
public class CANPercentQuadEncoderModeTest extends AbstractCANTest {
private static final Logger logger = Logger.getLogger(CANPercentQuadEncoderModeTest.class
.getName());
private static final double kStoppedValue = 0;
private static final double kRunningValue = 1;
/*
* (non-Javadoc)
*$
* @see edu.wpi.first.wpilibj.can.AbstractCANTest#stopMotor()
*/
protected void stopMotor() {
getME().getMotor().set(kStoppedValue);
}
/*
* (non-Javadoc)
*$
* @see edu.wpi.first.wpilibj.can.AbstractCANTest#runMotorForward()
*/
protected void runMotorForward() {
getME().getMotor().set(kRunningValue);
}
/*
* (non-Javadoc)
*$
* @see edu.wpi.first.wpilibj.can.AbstractCANTest#runMotorReverse()
*/
protected void runMotorReverse() {
getME().getMotor().set(-kRunningValue);
}
@Override
protected Logger getClassLogger() {
return logger;
}
@Before
public void setUp() {
getME().getMotor().setPercentMode(CANJaguar.kQuadEncoder, 360);
getME().getMotor().enableControl();
getME().getMotor().set(0.0f);
/* The motor might still have momentum from the previous test. */
Timer.delay(kStartupTime);
}
@Test
public void testDisableStopsTheMotor() {
// given
getME().getMotor().enableControl();
setCANJaguar(kMotorTime / 2, 1);
getME().getMotor().disableControl();
// when
simpleLog(Level.FINER, "The motor should stop running now");
setCANJaguar(kMotorTime / 2, 1);
final double initialPosition = getME().getMotor().getPosition();
setCANJaguar(kMotorTime / 2, 1);
// then
assertEquals("Speed did not go to zero when disabled in percent mode", 0, getME().getMotor()
.getSpeed(), kEncoderSpeedTolerance);
assertEquals(initialPosition, getME().getMotor().getPosition(), 10);
}
@Test
public void testRotateForward() {
// Given
getME().getMotor().enableControl();
final double initialPosition = getME().getMotor().getPosition();
// When
/* Drive the speed controller briefly to move the encoder */
runMotorForward();
// Then
PollingWait wait =
new PollingWait().timeoutAfter((long) kMotorTimeSettling, TimeUnit.SECONDS).pollEvery(1,
TimeUnit.MILLISECONDS);
wait.until(new RunnableAssert("CANJaguar position incrementing") {
@Override
public void run() throws Exception {
runMotorForward();
assertThat("CANJaguar position should have increased after the motor moved", getME()
.getMotor().getPosition(), is(greaterThan(initialPosition)));
}
});
stopMotor();
}
@Test
public void testRotateReverse() {
// Given
getME().getMotor().enableControl();
final double initialPosition = getME().getMotor().getPosition();
// When
/* Drive the speed controller briefly to move the encoder */
runMotorReverse();
// Then
PollingWait wait =
new PollingWait().timeoutAfter((long) kMotorTimeSettling, TimeUnit.SECONDS).pollEvery(1,
TimeUnit.MILLISECONDS);
wait.until(new RunnableAssert("CANJaguar position decrementing") {
@Override
public void run() throws Exception {
runMotorReverse();
assertThat("CANJaguar position should have decreased after the motor moved", getME()
.getMotor().getPosition(), is(lessThan(initialPosition)));
}
});
stopMotor();
}
/**
* Test if we can limit the Jaguar to not rotate forwards when the fake limit
* switch is tripped
*/
@Test
public void shouldNotRotateForwards_WhenFakeLimitSwitchForwardsIsTripped() {
// Given
getME().getMotor().configLimitMode(CANJaguar.LimitMode.SwitchInputsOnly);
getME().getForwardLimit().set(true);
getME().getReverseLimit().set(false);
getME().getMotor().enableControl();
stopMotor();
Timer.delay(kEncoderSettlingTime);
PollingWait wait =
new PollingWait().timeoutAfter((long) kLimitSettlingTime, TimeUnit.SECONDS).pollEvery(1,
TimeUnit.MILLISECONDS);
/* Wait until the limits are recognized by the CANJaguar. */
wait.until(new RunnableAssert(
"Waiting for the forward and reverse limit switches to be in the correct state") {
@Override
public void run() throws Exception {
stopMotor();
assertFalse("[TEST SETUP] The forward limit switch is not in the correct state", getME()
.getMotor().getForwardLimitOK());
assertTrue("[TEST SETUP]The reverse limit switch is not in the correct state", getME()
.getMotor().getReverseLimitOK());
}
});
final double initialPosition = getME().getMotor().getPosition();
// When
/*
* Drive the speed controller briefly to move the encoder. If the limit
* switch is recognized, it shouldn't actually move.
*/
setCANJaguar(kMotorTime, 1);
stopMotor();
// Then
/* The position should be the same, since the limit switch was on. */
assertEquals("CAN Jaguar should not have moved with the forward limit switch pressed",
initialPosition, getME().getMotor().getPosition(), kEncoderPositionTolerance);
}
/**
* Test if we can rotate in reverse when the limit switch
*/
@Test
public void shouldRotateReverse_WhenFakeLimitSwitchForwardsIsTripped() {
// Given
getME().getMotor().configLimitMode(CANJaguar.LimitMode.SwitchInputsOnly);
getME().getForwardLimit().set(true);
getME().getReverseLimit().set(false);
getME().getMotor().enableControl();
stopMotor();
Timer.delay(kEncoderSettlingTime);
PollingWait limitWait =
new PollingWait().timeoutAfter((long) kLimitSettlingTime, TimeUnit.SECONDS).pollEvery(1,
TimeUnit.MILLISECONDS);
/* Wait until the limits are recognized by the CANJaguar. */
limitWait.until(new RunnableAssert(
"Waiting for the forward and reverse limit switches to be in the correct state") {
@Override
public void run() throws Exception {
stopMotor();
assertFalse("[TEST SETUP] The forward limit switch is not in the correct state", getME()
.getMotor().getForwardLimitOK());
assertTrue("[TEST SETUP] The reverse limit switch is not in the correct state", getME()
.getMotor().getReverseLimitOK());
}
});
final double initialPosition = getME().getMotor().getPosition();
// When
/*
* Drive the speed controller in the other direction. It should actually
* move, since only the forward switch is activated.
*/
setCANJaguar(kMotorTime, -1);
// Then
PollingWait wait =
new PollingWait().timeoutAfter((long) kMotorTimeSettling, TimeUnit.SECONDS).pollEvery(1,
TimeUnit.MILLISECONDS);
wait.until(new RunnableAssert("Waiting for the encoder to update") {
@Override
public void run() throws Exception {
runMotorReverse();
assertThat("CAN Jaguar should have moved in reverse while the forward limit was on",
getME().getMotor().getPosition(), is(lessThan(initialPosition)));
}
});
stopMotor();
}
/**
* Test if we can limit the Jaguar to only moving forwards with a fake limit
* switch.
*/
@Test
public void shouldNotRotateReverse_WhenFakeLimitSwitchReversesIsTripped() {
// Given
getME().getMotor().configLimitMode(CANJaguar.LimitMode.SwitchInputsOnly);
getME().getForwardLimit().set(false);
getME().getReverseLimit().set(true);
getME().getMotor().enableControl();
stopMotor();
Timer.delay(kEncoderSettlingTime);
PollingWait wait =
new PollingWait().timeoutAfter((long) kLimitSettlingTime, TimeUnit.SECONDS).pollEvery(1,
TimeUnit.MILLISECONDS);
/* Wait until the limits are recognized by the CANJaguar. */
wait.until(new RunnableAssert(
"Waiting for the forward and reverse limit switches to be in the correct state") {
@Override
public void run() throws Exception {
stopMotor();
assertTrue("[TEST SETUP] The forward limit switch is not in the correct state", getME()
.getMotor().getForwardLimitOK());
assertFalse("[TEST SETUP] The reverse limit switch is not in the correct state", getME()
.getMotor().getReverseLimitOK());
}
});
final double initialPosition = getME().getMotor().getPosition();
// When
/*
* Drive the speed controller backwards briefly to move the encoder. If the
* limit switch is recognized, it shouldn't actually move.
*/
setCANJaguar(kMotorTime, -1);
stopMotor();
// Then
/* The position should be the same, since the limit switch was on. */
assertEquals("CAN Jaguar should not have moved with the limit switch pressed", initialPosition,
getME().getMotor().getPosition(), kEncoderPositionTolerance);
}
/**
* Test if we can limit the Jaguar to only moving forwards with a fake limit
* switch.
*/
/**
*$
*/
@Test
public void shouldRotateForward_WhenFakeLimitSwitchReversesIsTripped() {
// Given
getME().getMotor().configLimitMode(CANJaguar.LimitMode.SwitchInputsOnly);
getME().getForwardLimit().set(false);
getME().getReverseLimit().set(true);
getME().getMotor().enableControl();
PollingWait limitWait =
new PollingWait().timeoutAfter((long) kLimitSettlingTime, TimeUnit.SECONDS).pollEvery(1,
TimeUnit.MILLISECONDS);
/* Wait until the limits are recognized by the CANJaguar. */
limitWait.until(new RunnableAssert(
"Waiting for the forward and reverse limit switches to be in the correct state") {
@Override
public void run() throws Exception {
stopMotor();
assertTrue("[TEST SETUP] The forward limit switch is not in the correct state", getME()
.getMotor().getForwardLimitOK());
assertFalse("[TEST SETUP] The reverse limit switch is not in the correct state", getME()
.getMotor().getReverseLimitOK());
}
});
final double initialPosition = getME().getMotor().getPosition();
// When
/*
* Drive the speed controller in the other direction. It should actually
* move, since only the reverse switch is activated.
*/
setCANJaguar(kMotorTime, 1);
// Then
/* The position should have increased */
PollingWait wait =
new PollingWait().timeoutAfter((long) kMotorTimeSettling, TimeUnit.SECONDS).pollEvery(1,
TimeUnit.MILLISECONDS);
wait.until(new RunnableAssert("Waiting for the encoder to update") {
@Override
public void run() throws Exception {
runMotorForward();
assertThat("CAN Jaguar should have moved forwards while the reverse limit was on", getME()
.getMotor().getPosition(), is(greaterThan(initialPosition)));
}
});
stopMotor();
}
@Ignore("Encoder is not yet wired to the FPGA")
@Test
public void testRotateForwardEncoderToFPGA() {
getME().getMotor().enableControl();
final double jagInitialPosition = getME().getMotor().getPosition();
final double encoderInitialPosition = getME().getEncoder().get();
getME().getMotor().set(1);
Timer.delay(kMotorStopTime);
getME().getMotor().set(0);
delayTillInCorrectStateWithMessage(Level.FINE, kEncoderSettlingTime,
"Forward Encodeder settling", new BooleanCheck() {
@Override
public boolean getAsBoolean() {
return Math.abs((getME().getMotor().getPosition() - jagInitialPosition)
- (getME().getEncoder().get() - encoderInitialPosition)) < kEncoderPositionTolerance;
}
});
assertEquals(getME().getMotor().getPosition() - jagInitialPosition, getME().getEncoder().get()
- encoderInitialPosition, kEncoderPositionTolerance);
}
@Ignore("Encoder is not yet wired to the FPGA")
@Test
public void testRotateReverseEncoderToFPGA() {
getME().getMotor().enableControl();
final double jagInitialPosition = getME().getMotor().getPosition();
final double encoderInitialPosition = getME().getEncoder().get();
getME().getMotor().set(-1);
Timer.delay(kMotorStopTime);
getME().getMotor().set(0);
delayTillInCorrectStateWithMessage(Level.FINE, kEncoderSettlingTime,
"Forward Encodeder settling", new BooleanCheck() {
@Override
public boolean getAsBoolean() {
return Math.abs((getME().getMotor().getPosition() - jagInitialPosition)
- (getME().getEncoder().get() - encoderInitialPosition)) < kEncoderPositionTolerance;
}
});
assertEquals(getME().getMotor().getPosition() - jagInitialPosition, getME().getEncoder().get()
- encoderInitialPosition, kEncoderPositionTolerance);
}
}

View File

@@ -0,0 +1,170 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008-2014. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.can;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import com.googlecode.junittoolbox.PollingWait;
import com.googlecode.junittoolbox.RunnableAssert;
import edu.wpi.first.wpilibj.CANJaguar;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.fixtures.MotorEncoderFixture;
/**
* @author jonathanleitschuh
*
*/
public class CANPositionPotentiometerModeTest extends AbstractCANTest {
private static final Logger logger = Logger.getLogger(CANPositionPotentiometerModeTest.class
.getName());
private static final double kStoppedValue = 0;
private static final int defaultPotAngle = 180;
private static final double maxPotVoltage = 3.0;
/*
* (non-Javadoc)
*$
* @see edu.wpi.first.wpilibj.can.AbstractCANTest#stopMotor()
*/
protected void stopMotor() {
getME().getMotor().set(.5);
}
/*
* (non-Javadoc)
*$
* @see edu.wpi.first.wpilibj.can.AbstractCANTest#runMotorForward()
*/
protected void runMotorForward() {
getME().getMotor().set(1);
}
/*
* (non-Javadoc)
*$
* @see edu.wpi.first.wpilibj.can.AbstractCANTest#runMotorReverse()
*/
protected void runMotorReverse() {
getME().getMotor().set(0);
}
@Override
protected Logger getClassLogger() {
return logger;
}
@Before
public void setUp() throws Exception {
getME().getMotor().setPositionMode(CANJaguar.kPotentiometer, 5.0, 0.1, 2.0);
// getME().getMotor().configPotentiometerTurns(rotationRange);
getME().getFakePot().setMaxVoltage(maxPotVoltage);
getME().getFakePot().setVoltage(1.5);
stopMotor();
getME().getMotor().enableControl();
/* The motor might still have momentum from the previous test. */
Timer.delay(kStartupTime);
}
/**
* NOTICE: This is using the {@link MotorEncoderFixture#getEncoder()} instead
* of the one built into the CAN Jaguar
*/
@Ignore("Encoder is not yet wired to the FPGA")
@Test
public void testRotateForward() {
int initialPosition = getME().getEncoder().get();
/* Drive the speed controller briefly to move the encoder */
getME().getMotor().set(kStoppedValue);
Timer.delay(kMotorTimeSettling);
getME().getMotor().set(defaultPotAngle);
/* The position should have increased */
assertThat("CAN Jaguar position should have increased after the motor moved", getME()
.getEncoder().get(), is(greaterThan(initialPosition)));
}
/**
* NOTICE: This is using the {@link MotorEncoderFixture#getEncoder()} instead
* of the one built into the CAN Jaguar
*/
@Ignore("Encoder is not yet wired to the FPGA")
@Test
public void testRotateReverse() {
int initialPosition = getME().getEncoder().get();
/* Drive the speed controller briefly to move the encoder */
getME().getMotor().set(kStoppedValue);
Timer.delay(kMotorTimeSettling);
getME().getMotor().set(defaultPotAngle);
/* The position should have increased */
assertThat("CAN Jaguar position should have increased after the motor moved", getME()
.getEncoder().get(), is(greaterThan(initialPosition)));
}
/**
* Test if we can get a position in potentiometer mode, using an analog output
* as a fake potentiometer.
*/
@Test
public void testFakePotentiometerPosition() {
// TODO When https://github.com/Pragmatists/JUnitParams/issues/5 is resolved
// make this test parameterized
// Given
PollingWait wait =
new PollingWait().timeoutAfter((long) kPotentiometerSettlingTime, TimeUnit.SECONDS)
.pollEvery(1, TimeUnit.MILLISECONDS);
RunnableAssert assertion =
new RunnableAssert("Waiting for potentiometer position to be correct") {
@Override
public void run() throws Exception {
getME().getMotor().set(0);
assertEquals(
"CAN Jaguar should have returned the potentiometer position set by the analog output",
getME().getFakePot().getVoltage(), getME().getMotor().getPosition() * 3,
kPotentiometerPositionTolerance * 3);
}
};
// When
getME().getFakePot().setVoltage(0.0);
// Then
wait.until(assertion);
// When
getME().getFakePot().setVoltage(1.0);
// Then
wait.until(assertion);
// When
getME().getFakePot().setVoltage(2.0);
// Then
wait.until(assertion);
// When
getME().getFakePot().setVoltage(3.0);
// Then
wait.until(assertion);
}
}

View File

@@ -0,0 +1,120 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008-2014. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.can;
import static org.junit.Assert.assertEquals;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import edu.wpi.first.wpilibj.CANJaguar;
import edu.wpi.first.wpilibj.Timer;
/**
* @author jonathanleitschuh
*
*/
public class CANPositionQuadEncoderModeTest extends AbstractCANTest {
private static final Logger logger = Logger.getLogger(CANPositionQuadEncoderModeTest.class
.getName());
@Override
protected Logger getClassLogger() {
return logger;
}
/*
* (non-Javadoc)
*$
* @see edu.wpi.first.wpilibj.can.AbstractCANTest#runMotorForward()
*/
protected void runMotorForward() {
double postion = getME().getMotor().getPosition();
getME().getMotor().set(postion + 100);
}
/*
* (non-Javadoc)
*$
* @see edu.wpi.first.wpilibj.can.AbstractCANTest#runMotorReverse()
*/
protected void runMotorReverse() {
double postion = getME().getMotor().getPosition();
getME().getMotor().set(postion - 100);
}
@Before
public void setUp() throws Exception {
getME().getMotor().setPositionMode(CANJaguar.kQuadEncoder, 360, 10.0f, 0.01f, 0.0f);
getME().getMotor().enableControl(0);
/* The motor might still have momentum from the previous test. */
Timer.delay(kStartupTime);
}
@Ignore("The encoder initial position is not validated so is sometimes not set properly")
@Test
public void testSetEncoderInitialPositionWithEnable() {
// given
final double encoderValue = 4823;
// when
getME().getMotor().enableControl(encoderValue);
getME().getMotor().disableControl();
delayTillInCorrectStateWithMessage(Level.FINE, kEncoderSettlingTime, "Encoder value settling",
new BooleanCheck() {
@Override
public boolean getAsBoolean() {
getME().getMotor().set(getME().getMotor().getPosition());
return Math.abs(getME().getMotor().getPosition() - encoderValue) < 40;
}
});
// then
assertEquals(encoderValue, getME().getMotor().getPosition(), 40);
}
/**
* Test if we can set a position and reach that position with PID control on
* the Jaguar.
*/
@Test
public void testEncoderPositionPIDForward() {
double setpoint = getME().getMotor().getPosition() + 1.0f;
/* It should get to the setpoint within 10 seconds */
getME().getMotor().set(setpoint);
setCANJaguar(kMotorTimeSettling, setpoint);
assertEquals("CAN Jaguar should have reached setpoint with PID control", setpoint, getME()
.getMotor().getPosition(), kEncoderPositionTolerance);
}
/**
* Test if we can set a position and reach that position with PID control on
* the Jaguar.
*/
@Test
public void testEncoderPositionPIDReverse() {
double setpoint = getME().getMotor().getPosition() - 1.0f;
/* It should get to the setpoint within 10 seconds */
getME().getMotor().set(setpoint);
setCANJaguar(kMotorTimeSettling, setpoint);
assertEquals("CAN Jaguar should have reached setpoint with PID control", setpoint, getME()
.getMotor().getPosition(), kEncoderPositionTolerance);
}
}

View File

@@ -0,0 +1,86 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008-2014. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.can;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.lessThan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import java.util.logging.Logger;
import org.junit.Before;
import org.junit.Test;
import edu.wpi.first.wpilibj.CANJaguar;
import edu.wpi.first.wpilibj.Timer;
/**
* @author jonathanleitschuh
*
*/
public class CANSpeedQuadEncoderModeTest extends AbstractCANTest {
private static final Logger logger = Logger.getLogger(CANPercentQuadEncoderModeTest.class
.getName());
/** The stopped value in rev/min */
private static final double kStoppedValue = 0;
/** The running value in rev/min */
private static final double kRunningValue = 200;
@Override
protected Logger getClassLogger() {
return logger;
}
@Before
public void setUp() throws Exception {
getME().getMotor().setSpeedMode(CANJaguar.kQuadEncoder, 360, 0.1f, 0.003f, 0.01f);
getME().getMotor().enableControl();
getME().getMotor().set(0.0f);
/* The motor might still have momentum from the previous test. */
Timer.delay(kStartupTime);
}
@Test
public void testDefaultSpeed() {
assertEquals("CAN Jaguar did not start with an initial speed of zero", 0.0f, getME().getMotor()
.getSpeed(), 0.3f);
}
/**
* Test if we can drive the motor forward in Speed mode and get a position
* back
*/
@Test
public void testRotateForwardSpeed() {
double speed = 50.0f;
double initialPosition = getME().getMotor().getPosition();
setCANJaguar(2 * kMotorTime, speed);
assertEquals("The motor did not reach the required speed in speed mode", speed, getME()
.getMotor().getSpeed(), kEncoderSpeedTolerance);
assertThat("The motor did not move forward in speed mode", getME().getMotor().getPosition(),
is(greaterThan(initialPosition)));
}
/**
* Test if we can drive the motor backwards in Speed mode and get a position
* back
*/
@Test
public void testRotateReverseSpeed() {
double speed = -50.0f;
double initialPosition = getME().getMotor().getPosition();
setCANJaguar(2 * kMotorTime, speed);
assertEquals("The motor did not reach the required speed in speed mode", speed, getME()
.getMotor().getSpeed(), kEncoderSpeedTolerance);
assertThat("The motor did not move in reverse in speed mode", getME().getMotor().getPosition(),
is(lessThan(initialPosition)));
}
}

View File

@@ -0,0 +1,26 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008-2014. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.can;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import edu.wpi.first.wpilibj.test.AbstractTestSuite;
/**
* @author jonathanleitschuh
*
*/
@RunWith(Suite.class)
@SuiteClasses({CANCurrentQuadEncoderModeTest.class, CANDefaultTest.class,
CANJaguarInversionTest.class, CANPercentQuadEncoderModeTest.class,
CANPositionPotentiometerModeTest.class, CANPositionQuadEncoderModeTest.class,
CANSpeedQuadEncoderModeTest.class, CANVoltageQuadEncoderModeTest.class})
public class CANTestSuite extends AbstractTestSuite {
}

View File

@@ -0,0 +1,219 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008-2014. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.can;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.lessThan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import org.junit.Before;
import org.junit.Test;
import com.googlecode.junittoolbox.PollingWait;
import com.googlecode.junittoolbox.RunnableAssert;
import edu.wpi.first.wpilibj.CANJaguar;
import edu.wpi.first.wpilibj.Timer;
/**
* @author jonathanleitschuh
*
*/
public class CANVoltageQuadEncoderModeTest extends AbstractCANTest {
private static final Logger logger = Logger.getLogger(CANVoltageQuadEncoderModeTest.class
.getName());
/** The stopped value in volts */
private static final double kStoppedValue = 0;
/** The running value in volts */
private static final double kRunningValue = 4;
private static final double kVoltageTolerance = .25;
private static final PollingWait kWait = new PollingWait().timeoutAfter(
(long) kMotorTimeSettling, TimeUnit.SECONDS).pollEvery(1, TimeUnit.MILLISECONDS);
/*
* (non-Javadoc)
*$
* @see edu.wpi.first.wpilibj.can.AbstractCANTest#stopMotor()
*/
protected void stopMotor() {
getME().getMotor().set(kStoppedValue);
}
/*
* (non-Javadoc)
*$
* @see edu.wpi.first.wpilibj.can.AbstractCANTest#runMotorForward()
*/
protected void runMotorForward() {
getME().getMotor().set(kRunningValue);
}
/*
* (non-Javadoc)
*$
* @see edu.wpi.first.wpilibj.can.AbstractCANTest#runMotorReverse()
*/
protected void runMotorReverse() {
getME().getMotor().set(-kRunningValue);
}
@Override
protected Logger getClassLogger() {
return logger;
}
@Before
public void setUp() throws Exception {
getME().getMotor().setVoltageMode(CANJaguar.kQuadEncoder, 360);
getME().getMotor().set(kStoppedValue);
getME().getMotor().enableControl();
/* The motor might still have momentum from the previous test. */
Timer.delay(kStartupTime);
}
@Test
public void testRotateForwardToVoltage() {
setCANJaguar(kMotorTime, Math.PI);
assertEquals("The output voltage did not match the desired voltage set-point", Math.PI, getME()
.getMotor().getOutputVoltage(), kVoltageTolerance);
}
@Test
public void testRotateReverseToVoltage() {
setCANJaguar(kMotorTime, -Math.PI);
assertEquals("The output voltage did not match the desired voltage set-point", -Math.PI,
getME().getMotor().getOutputVoltage(), kVoltageTolerance);
}
/**
* Sets up the test to have the CANJaguar running at the target voltage
*$
* @param targetValue the target voltage
* @param wait the PollingWait to to use to wait for the setup to complete
* with
*/
private void setupMotorVoltageForTest(final double targetValue, PollingWait wait) {
getME().getMotor().enableControl();
setCANJaguar(1, targetValue);
wait.until(new RunnableAssert(
"[SETUP] Waiting for the output voltage to match the set output value") {
@Override
public void run() throws Exception {
getME().getMotor().set(targetValue);
assertEquals("[TEST SETUP] The output voltage should have matched the set value",
targetValue, getME().getMotor().getOutputVoltage(), 0.5);
assertEquals("[TEST SETUP] The set value did not match the get value", targetValue, getME()
.getMotor().get(), 0.5);
}
});
}
@Test
public void testMaxOutputVoltagePositive() {
// given
double maxVoltage = 3;
setupMotorVoltageForTest(kRunningValue, kWait);
final double fastSpeed = getME().getMotor().getSpeed();
// when
getME().getMotor().configMaxOutputVoltage(maxVoltage);
setCANJaguar(1, kRunningValue);
// Then
kWait.until(new RunnableAssert("Waiting for the speed to reduce using max output voltage") {
@Override
public void run() throws Exception {
runMotorForward();
assertThat("Speed did not reduce when the max output voltage was set", fastSpeed,
is(greaterThan(getME().getMotor().getSpeed())));
}
});
}
@Test
public void testMaxOutputVoltagePositiveSetToZeroStopsMotor() {
// given
final double maxVoltage = 0;
setupMotorVoltageForTest(kRunningValue, kWait);
// when
getME().getMotor().configMaxOutputVoltage(maxVoltage);
setCANJaguar(1, kRunningValue);
// then
kWait.until(new RunnableAssert(
"Waiting for the speed to reduce to zero using max output voltage") {
@Override
public void run() throws Exception {
runMotorForward();
assertEquals("Speed did not go to zero when the max output voltage was set to "
+ maxVoltage, 0, getME().getMotor().getSpeed(), kEncoderSpeedTolerance);
}
});
}
@Test
public void testMaxOutputVoltageNegative() {
// given
double maxVoltage = 3;
setupMotorVoltageForTest(-kRunningValue, kWait);
final double fastSpeed = getME().getMotor().getSpeed();
// when
getME().getMotor().configMaxOutputVoltage(maxVoltage);
setCANJaguar(1, -kRunningValue);
// then
kWait.until(new RunnableAssert("Waiting for the speed to reduce using max output voltage") {
@Override
public void run() throws Exception {
runMotorReverse();
assertThat("Speed did not reduce when the max output voltage was set", fastSpeed,
is(lessThan(getME().getMotor().getSpeed())));
}
});
}
@Test
public void testMaxOutputVoltageNegativeSetToZeroStopsMotor() {
// given
final double maxVoltage = 0;
setupMotorVoltageForTest(-kRunningValue, kWait);
// when
getME().getMotor().configMaxOutputVoltage(maxVoltage);
setCANJaguar(1, -kRunningValue);
// Then
kWait.until(new RunnableAssert(
"Waiting for the speed to reduce to zero using max output voltage") {
@Override
public void run() throws Exception {
runMotorReverse();
assertEquals("Speed did not go to zero when the max output voltage was set to "
+ maxVoltage, 0, getME().getMotor().getSpeed(), kEncoderSpeedTolerance);
}
});
}
}

View File

@@ -0,0 +1,9 @@
/**
* Provides a suite of tests to cover CANJaguar fully in all different control
* modes and with each supported positional input. Different setup parameters
* are provided in each Test class. All test classes that want to take advantage
* of the default test setup frameworks in place should extend
* {@link AbstractCANTest}
*$
*/
package edu.wpi.first.wpilibj.can;