SCRIPT Move java files

This commit is contained in:
PJ Reiniger
2025-11-07 19:55:40 -05:00
committed by Peter Johnson
parent 7ca1be9bae
commit c350c5f112
1486 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.units;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
class CurrentUnitTest {
@Test
void testAmpsTimesVolts() {
PowerUnit combined = Units.Amps.mult(Units.Volts, "Watt", "w");
assertTrue(combined.equivalent(Units.Watts));
}
@Test
void testMilliAmpsTimesMilliVolts() {
// results in microwatts
PowerUnit times = Units.Milliamps.mult(Units.Millivolts, "Microwatt", "uW");
PowerUnit millimilli = Units.Milli(Units.Milliwatts);
assertEquals(1, times.convertFrom(1e-6, Units.Watts));
assertEquals(1, millimilli.convertFrom(1e-6, Units.Watts));
assertTrue(times.equivalent(millimilli));
}
}

View File

@@ -0,0 +1,35 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.units;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
class DistanceUnitTest {
@Test
void testBaseUnitDistancePerTime() {
LinearVelocityUnit anonBaseUnit =
new DistanceUnit(null, 1, "D", "d").per(new TimeUnit(null, 1, "T", "t"));
assertTrue(Units.MetersPerSecond.equivalent(anonBaseUnit));
}
@Test
void testFeetPerSecond() {
LinearVelocityUnit feetPerMillisecond = Units.Feet.per(Units.Milliseconds);
// one foot per millisecond
// = (1 / 3.28084) meters per (1 / 1000) seconds
// = (1000 / 3.28084) meters per second
double asBaseMeasure = feetPerMillisecond.of(1).in(Units.MetersPerSecond);
assertEquals(1000 / 3.28084, asBaseMeasure, 1e-3);
// one meter per second = 1 mm per millisecond = 0.00328084 feet per millisecond
double asContrivedMeasure = Units.MetersPerSecond.of(1).in(feetPerMillisecond);
assertEquals(3.28084 / 1000, asContrivedMeasure, 1e-8);
}
}

View File

@@ -0,0 +1,43 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.units;
class ExampleUnit extends Unit {
ExampleUnit(double baseUnitEquivalent) {
this(baseUnitEquivalent, "Example", "ex");
}
ExampleUnit(
ExampleUnit baseUnit,
UnaryFunction toBase,
UnaryFunction fromBase,
String name,
String symbol) {
super(baseUnit, toBase, fromBase, name, symbol);
}
ExampleUnit(double baseUnitEquivalent, String name, String symbol) {
super(null, baseUnitEquivalent, name, symbol);
}
public double convertFrom(double magnitude, ExampleUnit otherUnit) {
return fromBaseUnits(otherUnit.toBaseUnits(magnitude));
}
@Override
public Measure<ExampleUnit> of(double magnitude) {
return ImmutableMeasure.ofRelativeUnits(magnitude, this);
}
@Override
public Measure<ExampleUnit> ofBaseUnits(double baseUnitMagnitude) {
return ImmutableMeasure.ofBaseUnits(baseUnitMagnitude, this);
}
@Override
public VelocityUnit<ExampleUnit> per(TimeUnit time) {
return VelocityUnit.combine(this, time);
}
}

View File

@@ -0,0 +1,332 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.units;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import edu.wpi.first.units.measure.Angle;
import edu.wpi.first.units.measure.AngularMomentum;
import edu.wpi.first.units.measure.Distance;
import edu.wpi.first.units.measure.LinearVelocity;
import edu.wpi.first.units.measure.Per;
import edu.wpi.first.units.measure.Time;
import org.junit.jupiter.api.Test;
class MeasureTest {
@Test
void testBasics() {
DistanceUnit unit = Units.Feet;
double magnitude = 10;
Distance m = unit.of(magnitude);
assertEquals(unit, m.unit(), "Wrong units");
assertEquals(magnitude, m.magnitude(), 0, "Wrong magnitude");
}
@Test
void testMultiply() {
Distance m = Units.Feet.of(1);
Distance m2 = m.times(10);
assertEquals(10, m2.in(Units.Feet), 1e-12);
assertNotSame(m2, m); // make sure state wasn't changed
}
@Test
void testTimesConversionFactor() {
Distance m = Units.Feet.of(10);
Per<AngleUnit, DistanceUnit> conversion = Units.Degrees.of(10).div(Units.Feet.of(1));
Angle result = m.timesConversionFactor(conversion);
assertEquals(Units.Degrees.of(100), result);
}
@Test
void testTimesConversionFactorComplex() {
Distance m = Units.Feet.of(1);
// Using a complex compound unit here
// (Per<Mult<Mult<Mass, Per<Distance, Time>>, Distance>, Distance>)
Per<AngularMomentumUnit, DistanceUnit> conversion =
Units.KilogramMetersSquaredPerSecond.of(1).div(Units.Foot.one());
AngularMomentum result = m.timesConversionFactor(conversion);
assertEquals(Units.KilogramMetersSquaredPerSecond.of(1), result);
}
@Test
void testTimesVelocityConversionFactor() {
Time m = Units.Seconds.of(10);
LinearVelocity conversion = Units.MetersPerSecond.of(10);
Distance result = m.timesConversionFactor(conversion);
assertEquals(Units.Meters.of(100), result);
}
@Test
void testDivide() {
Distance m = Units.Meters.of(1);
Distance m2 = m.div(10);
assertEquals(0.1, m2.magnitude(), 0);
assertNotSame(m2, m);
}
@Test
void testAdd() {
Distance m1 = Units.Feet.of(1);
Distance m2 = Units.Inches.of(2);
assertTrue(m1.plus(m2).isEquivalent(Units.Feet.of(1 + 2 / 12d)));
assertTrue(m2.plus(m1).isEquivalent(Units.Inches.of(14)));
}
@Test
void testSubtract() {
Distance m1 = Units.Feet.of(1);
Distance m2 = Units.Inches.of(2);
assertTrue(m1.minus(m2).isEquivalent(Units.Feet.of(1 - 2 / 12d)));
assertTrue(m2.minus(m1).isEquivalent(Units.Inches.of(-10)));
}
@Test
void testUnaryMinus() {
Distance m = Units.Feet.of(123);
Distance negated = m.unaryMinus();
assertEquals(-123, negated.in(Units.Feet), 1e-12);
assertEquals(Units.Feet, negated.unit());
}
@Test
void testEquivalency() {
Distance inches = Units.Inches.of(12);
Distance feet = Units.Feet.of(1);
assertTrue(inches.isEquivalent(feet));
assertTrue(feet.isEquivalent(inches));
}
@Test
void testAs() {
Distance m = Units.Inches.of(12);
assertEquals(1, m.in(Units.Feet), Measure.EQUIVALENCE_THRESHOLD);
}
@Test
void testPerMeasureTime() {
var measure = Units.Kilograms.of(144);
var dt = Units.Milliseconds.of(53);
// 144 Kg / (53 ms) = (1000 / 53) * 144 Kg/s = (144,000 / 53) Kg/s
var result = measure.div(dt);
assertEquals(144_000.0 / 53, result.baseUnitMagnitude(), 1e-5);
assertEquals(Units.Kilograms.per(Units.Milliseconds), result.unit());
}
@Test
void testPerUnitTime() {
var measure = Units.Kilograms.of(144);
var result = measure.per(Units.Millisecond);
assertEquals(VelocityUnit.class, result.unit().getClass());
assertEquals(144_000.0, result.baseUnitMagnitude(), 1e-5);
assertEquals(Units.Kilograms.per(Units.Milliseconds), result.unit());
}
@Test
void testDivideMeasure() {
// Dimensionless divide
var m1 = Units.Meters.of(6);
var m2 = Units.Value.of(3);
var result = m1.div(m2);
assertEquals(2, m1.div(m2).magnitude());
assertEquals(Units.Meters, result.unit());
// Velocity divide
var m3 = Units.Meters.of(8);
var m4 = Units.Meters.per(Units.Second).of(4);
var time = m3.div(m4);
assertEquals(2, time.magnitude());
assertEquals(Units.Second, time.unit());
// PerUnit divide
var m5 = Units.Volts.of(6);
var m6 = Units.Volts.per(Units.Meter).of(2);
// Voltage/(Voltage/Distance) -> Voltage * Distance/Voltage -> Distance
var dist = m5.div(m6);
assertEquals(3, dist.magnitude());
assertEquals(Units.Meter, dist.unit());
}
@Test
void testToShortString() {
var measure = Units.Volts.of(343);
assertEquals("3.430e+02 V", measure.toShortString());
}
@Test
void testToLongString() {
var measure = Units.Volts.of(343);
assertEquals("343.0 Volt", measure.toLongString());
assertEquals("343.0001 Volt", Units.Volts.of(343.0001).toLongString());
assertEquals("1.2345678912345678E8 Volt", Units.Volts.of(123456789.12345678).toLongString());
}
@Test
void testOfBaseUnits() {
var unit = new ExampleUnit(16);
var measure = unit.ofBaseUnits(1);
assertEquals(unit, measure.unit());
assertEquals(1, measure.baseUnitMagnitude());
assertEquals(1 / 16.0, measure.magnitude());
}
@Test
@SuppressWarnings("SelfComparison")
void testCompare() {
var unit = new ExampleUnit(7);
var base = unit.of(1);
var less = unit.of(0.5);
var more = unit.of(2);
assertEquals(0, base.compareTo(base));
assertEquals(-1, base.compareTo(more));
assertEquals(1, base.compareTo(less));
// lt, lte, gt, gte helper functions
assertTrue(base.lt(more));
assertTrue(base.lte(more));
assertFalse(base.gt(more));
assertFalse(base.gte(more));
assertTrue(base.gt(less));
assertTrue(base.gte(less));
assertFalse(base.lt(less));
assertFalse(base.lte(less));
assertTrue(base.lte(base));
assertTrue(base.gte(base));
assertFalse(base.lt(base));
assertFalse(base.gt(base));
}
@Test
void testMinNoArgs() {
var min = Measure.min();
assertNull(min);
}
@Test
void testMin() {
var unit = new ExampleUnit(56.1);
var one = unit.of(1);
var two = unit.of(2);
var zero = unit.of(0);
var veryNegative = unit.of(-12839712);
var min = Measure.min(one, two, zero, veryNegative);
assertSame(veryNegative, min);
}
@Test
void testMaxNoArgs() {
var min = Measure.max();
assertNull(min);
}
@Test
void testMax() {
var unit = new ExampleUnit(6.551);
var one = unit.of(1);
var two = unit.of(2);
var zero = unit.of(0);
var veryLarge = unit.of(8217234);
var max = Measure.max(one, two, zero, veryLarge);
assertSame(veryLarge, max);
}
@Test
void testIsNearVarianceThreshold() {
var unit = new ExampleUnit(92);
var measureA = unit.of(1.21);
var measureB = unit.ofBaseUnits(64);
// A = 1.21 * 92 base units, or 111.32
// B = 64 base units
// ratio = 111.32 / 64 = 1.739375 = 173.9375%
assertTrue(measureA.isNear(measureA, 0));
assertTrue(measureB.isNear(measureB, 0));
assertFalse(measureA.isNear(measureB, 0));
assertFalse(measureA.isNear(measureB, 0.50));
assertFalse(measureA.isNear(measureB, 0.739370));
assertTrue(measureA.isNear(measureB, 0.739375));
assertTrue(measureA.isNear(measureB, 100)); // some stupidly large range +/- 10000%
var measureC = unit.of(-1.21);
var measureD = unit.ofBaseUnits(-64);
assertTrue(measureC.isNear(measureC, 0));
assertTrue(measureD.isNear(measureD, 0));
assertFalse(measureC.isNear(measureD, 0));
assertFalse(measureC.isNear(measureD, 0.50));
assertFalse(measureC.isNear(measureD, 0.739370));
assertTrue(measureC.isNear(measureD, 0.739375));
assertTrue(measureC.isNear(measureD, 100)); // some stupidly large range +/- 10000%
var measureE = Units.Meters.of(1);
var measureF = Units.Feet.of(-3.28084);
assertTrue(measureE.isNear(measureF, 2.01));
assertFalse(measureE.isNear(measureF, 1.99));
assertTrue(measureF.isNear(measureE, 2.01));
assertFalse(measureF.isNear(measureE, 1.99));
assertTrue(Units.Feet.zero().isNear(Units.Millimeters.zero(), 0.001));
assertFalse(Units.Feet.of(2).isNear(Units.Millimeters.of(0), 0.001));
}
@Test
void testIsNearMeasureTolerance() {
var measureCompared = Units.Meters.of(1);
var measureComparing = Units.Meters.of(1.2);
// Positive value with positive tolerance
assertTrue(measureCompared.isNear(measureComparing, Units.Millimeters.of(300)));
assertFalse(measureCompared.isNear(measureComparing, Units.Centimeters.of(10)));
measureCompared = measureCompared.unaryMinus();
measureComparing = measureComparing.unaryMinus();
// Negative value with positive tolerance
assertTrue(measureCompared.isNear(measureComparing, Units.Millimeters.of(300)));
assertFalse(measureCompared.isNear(measureComparing, Units.Centimeters.of(10)));
measureCompared = measureCompared.unaryMinus();
measureComparing = measureComparing.unaryMinus();
// Positive value with negative tolerance
assertTrue(measureCompared.isNear(measureComparing, Units.Millimeters.of(-300)));
assertFalse(measureCompared.isNear(measureComparing, Units.Centimeters.of(-10)));
measureCompared = measureCompared.unaryMinus();
measureComparing = measureComparing.unaryMinus();
// Negative value with negative tolerance.
assertTrue(measureCompared.isNear(measureComparing, Units.Millimeters.of(-300)));
assertFalse(measureCompared.isNear(measureComparing, Units.Centimeters.of(-10)));
measureCompared = measureCompared.unaryMinus();
measureComparing = measureComparing.unaryMinus();
// Tolerance exact difference between measures.
assertTrue(measureCompared.isNear(measureComparing, Units.Millimeters.of(200)));
assertTrue(measureCompared.isNear(measureComparing, Units.Centimeters.of(-20)));
}
}

View File

@@ -0,0 +1,37 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.units;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
import org.junit.jupiter.api.Test;
class MultUnitTest {
@Test
void testAutomaticNames() {
var unitA = new ExampleUnit(1, "Ay", "a");
var unitB = new ExampleUnit(1, "Bee", "b");
var mult = MultUnit.combine(unitA, unitB);
assertEquals("Ay-Bee", mult.name());
assertEquals("a*b", mult.symbol());
}
@Test
void testCombine() {
var unitA = new ExampleUnit(100);
var unitB = new ExampleUnit(0.912);
var mult = MultUnit.combine(unitA, unitB);
assertEquals(91.2, mult.toBaseUnits(1));
}
@Test
void testCaches() {
var unitA = new ExampleUnit(1);
var unitB = new ExampleUnit(2);
var mult = MultUnit.combine(unitA, unitB);
assertSame(mult, MultUnit.combine(unitA, unitB));
}
}

View File

@@ -0,0 +1,56 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.units;
import static edu.wpi.first.units.Units.Degrees;
import static edu.wpi.first.units.Units.Foot;
import static edu.wpi.first.units.Units.Inches;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertSame;
import org.junit.jupiter.api.Test;
class PerUnitTest {
@Test
void ofNative() {
ExampleUnit part = new ExampleUnit(1);
var unit = PerUnit.combine(part, part);
assertEquals(10, unit.ofNative(10).in(unit));
// Does not compile:
// unit.of(10).in(unit);
//
// error: incompatible types: PerUnit<ExampleUnit,ExampleUnit> cannot be converted to CAP#1
// unit.of(10).in(unit);
// ^
// where CAP#1 is a fresh type-variable:
// CAP#1 extends PerUnit<ExampleUnit,ExampleUnit>
// from capture of ? extends PerUnit<ExampleUnit,ExampleUnit>
// This is because `of` returns a `Measure<? extends PerUnit<ExampleUnit, ExampleUnit>>`,
// and a `Per<ExampleUnit, ExampleUnit>` object isn't a subtype of that anonymous wildcard bound
}
@Test
void multSameDenom() {
var unit = Degrees.per(Foot);
var result = unit.mult(Foot);
// Multiplying by the same unit as the divisor should return the dividend unit
assertSame(Degrees, result);
}
@Test
void multOtherDenom() {
var unit = Degrees.per(Foot);
// (Degrees / Foot) x Inches, or 1/12 of a degree
var result = unit.mult(Inches);
assertInstanceOf(AngleUnit.class, result);
assertEquals(1 / 12.0, result.of(1).in(Degrees), 1e-9);
assertEquals("Degree per Foot Inch", result.name());
assertEquals("°/ft-in", result.symbol());
}
}

View File

@@ -0,0 +1,102 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.units;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
class UnaryFunctionTest {
@Test
void testApply() {
UnaryFunction f = x -> x * x;
assertEquals(1, f.apply(1));
assertEquals(4, f.apply(2));
assertEquals(2, f.apply(1.414), 1e-3);
assertEquals(64, f.apply(-8));
}
@Test
void testPipeTo() {
UnaryFunction f = x -> x * x;
UnaryFunction g = x -> x + 1;
var h = f.pipeTo(g); // h(x) = g(f(x)) = x^2 + 1
assertEquals(2, h.apply(1));
assertEquals(65, h.apply(8));
}
@Test
void testMult() {
UnaryFunction f = x -> x * x;
UnaryFunction g = x -> x + 1;
var h = f.mult(g); // h(x) = f(x) * g(x) = (x^2)(x + 1) = x^3 + x^2
assertEquals(2, h.apply(1));
assertEquals(216 + 36, h.apply(6));
assertEquals(12, h.apply(2));
}
@Test
void testMultScalar() {
UnaryFunction f = x -> x * x;
var scalar = 2.5;
var h = f.mult(scalar); // h(x) = 2.5 x^2
assertEquals(250, h.apply(10));
assertEquals(2.5, h.apply(1));
assertEquals(2.5, h.apply(-1));
assertEquals(10, h.apply(2));
}
@Test
void testDivZeroDenominator() {
UnaryFunction f = x -> x;
UnaryFunction g = x -> 0;
var h = f.div(g);
assertEquals(0, h.apply(0));
assertEquals(Double.POSITIVE_INFINITY, h.apply(1));
assertEquals(Double.NEGATIVE_INFINITY, h.apply(-1));
}
@Test
void testDivNonzeroDenominator() {
UnaryFunction f = x -> 2 * x;
UnaryFunction g = x -> x + 1;
var h = f.div(g);
assertEquals(0, h.apply(0));
assertEquals(4, h.apply(-2));
assertEquals(16.0 / 9, h.apply(8));
}
@Test
void testDivScalar() {
UnaryFunction f = x -> x * x;
var scalar = 2.5;
var h = f.div(scalar); // h(x) = x^2 / 2.5
assertEquals(10, h.apply(5));
}
@Test
void testExp() {
UnaryFunction f = x -> x * x;
UnaryFunction g = x -> x + 2;
var h = f.exp(g); // h(x) = f(x) ^ g(x) = (x^2)^(x + 2)
assertEquals(1, h.apply(1));
assertEquals(0, h.apply(0));
assertEquals(1, h.apply(-2));
assertEquals(256, h.apply(2)); // (2^2)^(2 + 2) = 4^4
assertEquals(59049, h.apply(3)); // (3^2)^(3 + 2) = 9^5
}
@Test
void testExpScalar() {
UnaryFunction f = x -> x * x;
var scalar = 4;
var h = f.exp(scalar); // h(x) = f(x)^4 = x^8
assertEquals(0, h.apply(0));
assertEquals(1, h.apply(1));
assertEquals(1, h.apply(-1));
assertEquals(256, h.apply(2));
assertEquals(6561, h.apply(3));
}
}

View File

@@ -0,0 +1,19 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.units;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
class UnitTest { // :)
@Test
void testOf() {
ExampleUnit u = new ExampleUnit(1);
Measure<ExampleUnit> fiveOfSomething = u.of(5);
assertEquals(5, fiveOfSomething.magnitude(), 0);
assertEquals(u, fiveOfSomething.unit());
}
}

View File

@@ -0,0 +1,350 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.units;
import static edu.wpi.first.units.Units.Amps;
import static edu.wpi.first.units.Units.Celsius;
import static edu.wpi.first.units.Units.Centimeters;
import static edu.wpi.first.units.Units.Degrees;
import static edu.wpi.first.units.Units.Fahrenheit;
import static edu.wpi.first.units.Units.Feet;
import static edu.wpi.first.units.Units.FeetPerSecond;
import static edu.wpi.first.units.Units.Grams;
import static edu.wpi.first.units.Units.Gs;
import static edu.wpi.first.units.Units.Horsepower;
import static edu.wpi.first.units.Units.Inches;
import static edu.wpi.first.units.Units.Kelvin;
import static edu.wpi.first.units.Units.Kilo;
import static edu.wpi.first.units.Units.Kilograms;
import static edu.wpi.first.units.Units.Meters;
import static edu.wpi.first.units.Units.MetersPerSecond;
import static edu.wpi.first.units.Units.MetersPerSecondPerSecond;
import static edu.wpi.first.units.Units.Microseconds;
import static edu.wpi.first.units.Units.Milli;
import static edu.wpi.first.units.Units.Milliamps;
import static edu.wpi.first.units.Units.Millimeters;
import static edu.wpi.first.units.Units.Milliseconds;
import static edu.wpi.first.units.Units.Millivolts;
import static edu.wpi.first.units.Units.Milliwatts;
import static edu.wpi.first.units.Units.Minutes;
import static edu.wpi.first.units.Units.Ounces;
import static edu.wpi.first.units.Units.Percent;
import static edu.wpi.first.units.Units.Pounds;
import static edu.wpi.first.units.Units.Radians;
import static edu.wpi.first.units.Units.Revolutions;
import static edu.wpi.first.units.Units.Second;
import static edu.wpi.first.units.Units.Seconds;
import static edu.wpi.first.units.Units.Value;
import static edu.wpi.first.units.Units.Volts;
import static edu.wpi.first.units.Units.Watts;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.function.DoubleFunction;
import org.junit.jupiter.api.Test;
class UnitsTest {
// Be accurate to 0.01%
private static final double thresh = 1e-5;
void testBaseUnit(DoubleFunction<Measure<?>> baseUnit) {
assertEquals(0, baseUnit.apply(0).baseUnitMagnitude(), 0);
assertEquals(1, baseUnit.apply(1).baseUnitMagnitude(), 0);
assertEquals(-1, baseUnit.apply(-1).baseUnitMagnitude(), 0);
assertEquals(100, baseUnit.apply(100).baseUnitMagnitude(), 0);
assertEquals(8.281723, baseUnit.apply(8.281723).baseUnitMagnitude(), 0);
assertEquals(Float.MAX_VALUE, baseUnit.apply(Float.MAX_VALUE).baseUnitMagnitude(), 0);
assertEquals(Float.MIN_VALUE, baseUnit.apply(Float.MIN_VALUE).baseUnitMagnitude(), 0);
}
// Distances
@Test
void testMeters() {
testBaseUnit(Meters::of);
assertEquals("Meter", Meters.name());
assertEquals("m", Meters.symbol());
}
@Test
void testMillimeters() {
assertEquals(1000, Millimeters.convertFrom(1, Meters), thresh);
assertEquals(1, Meters.convertFrom(1000, Millimeters), thresh);
assertEquals("Millimeter", Millimeters.name());
assertEquals("mm", Millimeters.symbol());
}
@Test
void testCentimeters() {
assertEquals(100, Centimeters.convertFrom(1, Meters), thresh);
assertEquals(1, Meters.convertFrom(100, Centimeters), thresh);
assertEquals("Centimeter", Centimeters.name());
assertEquals("cm", Centimeters.symbol());
}
@Test
void testInches() {
assertEquals(1, Meters.convertFrom(39.3701, Inches), thresh);
assertEquals(39.3701, Inches.convertFrom(1, Meters), 1e-4);
assertEquals(1 / 25.4, Inches.convertFrom(1, Millimeters), 0); // should be exact
assertEquals(12, Inches.convertFrom(1, Feet), thresh);
assertEquals("Inch", Inches.name());
assertEquals("in", Inches.symbol());
}
@Test
void testFeet() {
assertEquals(3.28084, Feet.convertFrom(1, Meters), thresh);
assertEquals(1 / 12.0, Feet.convertFrom(1, Inches), thresh);
assertEquals("Foot", Feet.name());
assertEquals("ft", Feet.symbol());
}
// Velocities
@Test
void testMetersPerSecond() {
testBaseUnit(MetersPerSecond::of);
assertEquals("Meter per Second", MetersPerSecond.name());
assertEquals("m/s", MetersPerSecond.symbol());
}
@Test
void testFeetPerSecond() {
assertEquals(3.28084, FeetPerSecond.convertFrom(1, MetersPerSecond), thresh);
assertEquals(1 / 3.28084, MetersPerSecond.convertFrom(1, FeetPerSecond), thresh);
assertEquals("Foot per Second", FeetPerSecond.name());
assertEquals("ft/s", FeetPerSecond.symbol());
}
// Accelerations
@Test
void testMetersPerSecondPerSecond() {
testBaseUnit(MetersPerSecondPerSecond::of);
assertEquals("Meter per Second per Second", MetersPerSecondPerSecond.name());
assertEquals("m/s/s", MetersPerSecondPerSecond.symbol());
assertEquals(MetersPerSecond, MetersPerSecondPerSecond.getUnit());
assertEquals(Seconds, MetersPerSecondPerSecond.getPeriod());
}
@Test
void testGs() {
assertEquals(32.17405, Gs.of(1).in(FeetPerSecond.per(Second)), thresh);
assertEquals(9.80665, Gs.of(1).in(MetersPerSecondPerSecond), thresh);
assertEquals("G", Gs.name());
assertEquals("G", Gs.symbol());
assertEquals(MetersPerSecond, Gs.getUnit());
assertEquals(Seconds, Gs.getPeriod());
}
// Time
@Test
void testSeconds() {
testBaseUnit(Seconds::of);
assertEquals("Second", Seconds.name());
assertEquals("s", Seconds.symbol());
}
@Test
void testMillisecond() {
assertEquals(1000, Milliseconds.convertFrom(1, Seconds), thresh);
assertEquals("Millisecond", Milliseconds.name());
assertEquals("ms", Milliseconds.symbol());
}
@Test
void testMicrosecond() {
assertEquals(1e6, Microseconds.convertFrom(1, Second), 0);
assertEquals("Microsecond", Microseconds.name());
assertEquals("us", Microseconds.symbol());
}
@Test
void testMinutes() {
assertEquals(60, Seconds.convertFrom(1, Minutes), thresh);
assertEquals("Minute", Minutes.name());
assertEquals("min", Minutes.symbol());
}
// Mass
@Test
void testKilograms() {
testBaseUnit(Kilograms::of);
assertEquals("Kilogram", Kilograms.name());
assertEquals("Kg", Kilograms.symbol());
}
@Test
void testGrams() {
assertEquals(1000, Grams.convertFrom(1, Kilograms), thresh);
assertEquals("Gram", Grams.name());
assertEquals("g", Grams.symbol());
}
@Test
void testPounds() {
assertEquals(453.592, Grams.convertFrom(1, Pounds), thresh);
assertEquals("Pound", Pounds.name());
assertEquals("lb.", Pounds.symbol());
}
@Test
void testOunces() {
assertEquals(16, Ounces.convertFrom(1, Pounds), thresh);
assertEquals("Ounce", Ounces.name());
assertEquals("oz.", Ounces.symbol());
}
// Angle
@Test
void testRevolutions() {
assertEquals(1, Revolutions.convertFrom(2 * Math.PI, Radians), thresh);
assertEquals("Revolution", Revolutions.name());
assertEquals("R", Revolutions.symbol());
}
@Test
void testRadians() {
testBaseUnit(Radians::of);
assertEquals(2 * Math.PI, Radians.convertFrom(1, Revolutions), thresh);
assertEquals(2 * Math.PI, Radians.convertFrom(360, Degrees), thresh);
assertEquals("Radian", Radians.name());
assertEquals("rad", Radians.symbol());
}
@Test
void testDegrees() {
assertEquals(360, Degrees.convertFrom(1, Revolutions), thresh);
assertEquals(360, Degrees.convertFrom(2 * Math.PI, Radians), thresh);
assertEquals("Degree", Degrees.name());
assertEquals("°", Degrees.symbol());
}
// Unitless
@Test
void testValue() {
testBaseUnit(Value::of);
assertEquals("<?>", Value.name());
assertEquals("<?>", Value.symbol());
}
@Test
void testPercent() {
assertEquals(100, Percent.convertFrom(1, Value), thresh);
assertEquals("Percent", Percent.name());
assertEquals("%", Percent.symbol());
}
// Electric potential
@Test
void testVolts() {
testBaseUnit(Volts::of);
assertEquals("Volt", Volts.name());
assertEquals("V", Volts.symbol());
}
@Test
void testMillivolts() {
assertEquals(1000, Millivolts.convertFrom(1, Volts), thresh);
assertEquals("Millivolt", Millivolts.name());
assertEquals("mV", Millivolts.symbol());
}
// Electric current
@Test
void testAmps() {
testBaseUnit(Amps::of);
assertEquals("Amp", Amps.name());
assertEquals("A", Amps.symbol());
}
@Test
void testMilliamps() {
assertEquals(1000, Milliamps.convertFrom(1, Amps), thresh);
assertEquals("Milliamp", Milliamps.name());
assertEquals("mA", Milliamps.symbol());
}
// Power
@Test
void testWatts() {
testBaseUnit(Watts::of);
assertEquals("Watt", Watts.name());
assertEquals("W", Watts.symbol());
}
@Test
void testMilliwatts() {
assertEquals(1000, Milliwatts.convertFrom(1, Watts), thresh);
assertEquals("Milliwatt", Milliwatts.name());
assertEquals("mW", Milliwatts.symbol());
}
@Test
void testHorsepower() {
assertEquals(745.7, Watts.convertFrom(1, Horsepower), thresh);
assertEquals("Horsepower", Horsepower.name());
assertEquals("HP", Horsepower.symbol());
}
// Temperature
@Test
void testKelvin() {
testBaseUnit(Kelvin::of);
assertEquals("Kelvin", Kelvin.name());
assertEquals("K", Kelvin.symbol()); // note: there's no degree symbol for Kelvin!
}
@Test
void testCelsius() {
assertEquals(0, Celsius.of(-273.15).in(Kelvin), thresh);
assertEquals(273.15, Celsius.of(0).in(Kelvin), thresh);
assertEquals(0, Kelvin.of(273.15).in(Celsius), thresh);
assertTrue(Celsius.of(0).isEquivalent(Kelvin.of(273.15)));
assertTrue(Celsius.of(-273.15).isEquivalent(Kelvin.of(0)));
assertEquals("Celsius", Celsius.name());
assertEquals("°C", Celsius.symbol());
}
@Test
void testFahrenheit() {
assertEquals(0, Fahrenheit.of(32).in(Celsius), thresh);
assertEquals(100, Fahrenheit.of(212).in(Celsius), thresh);
assertEquals(-459.67, Kelvin.of(0).in(Fahrenheit), thresh);
assertEquals(273.15, Fahrenheit.of(32).in(Kelvin), thresh);
assertEquals(32, Kelvin.of(273.15).in(Fahrenheit), thresh);
assertTrue(Fahrenheit.of(32).isEquivalent(Celsius.of(0)));
assertTrue(Fahrenheit.of(212).isEquivalent(Celsius.of(100)));
assertEquals("Fahrenheit", Fahrenheit.name());
assertEquals("°F", Fahrenheit.symbol());
}
// Helpers
@Test
void testKilo() {
ExampleUnit unit = new ExampleUnit(1);
ExampleUnit kiloUnit = Kilo(unit);
assertEquals(1e3, unit.convertFrom(1, kiloUnit), 0);
assertEquals(1e-3, kiloUnit.convertFrom(1, unit), 0);
}
@Test
void testMilli() {
ExampleUnit unit = new ExampleUnit(1);
ExampleUnit milliUnit = Milli(unit);
assertEquals(1e-3, unit.convertFrom(1, milliUnit), 0);
assertEquals(1e3, milliUnit.convertFrom(1, unit), 0);
}
}

View File

@@ -0,0 +1,63 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.units;
import static edu.wpi.first.units.Units.Feet;
import static edu.wpi.first.units.Units.FeetPerSecond;
import static edu.wpi.first.units.Units.Meters;
import static edu.wpi.first.units.Units.MetersPerSecond;
import static edu.wpi.first.units.Units.MetersPerSecondPerSecond;
import static edu.wpi.first.units.Units.Millisecond;
import static edu.wpi.first.units.Units.Minute;
import static edu.wpi.first.units.Units.Radians;
import static edu.wpi.first.units.Units.Second;
import static edu.wpi.first.units.Units.Seconds;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
class VelocityUnitTest {
@Test
void testBaseUnit() {
assertTrue(MetersPerSecond.equivalent(MetersPerSecond));
assertTrue(Meters.per(Second).equivalent(MetersPerSecond));
}
@Test
void testToAcceleration() {
LinearAccelerationUnit metersPerSecondPerMillisecond = MetersPerSecond.per(Millisecond);
assertEquals(1000, metersPerSecondPerMillisecond.of(1).in(MetersPerSecondPerSecond), 0);
assertEquals(0, metersPerSecondPerMillisecond.of(0).in(MetersPerSecondPerSecond), 0);
}
@Test
void testCache() {
assertSame(
FeetPerSecond, Feet.per(Second), "Feet.per(Second) should return a cached object instance");
// completely arbitrary units chosen because they won't have already been cached
var someDistance = new AngleUnit(Radians, 123, "a", "a");
var someTime = new TimeUnit(Seconds, 123, "t", "t");
var firstInvocation = someDistance.per(someTime);
var secondInvocation = someDistance.per(someTime);
assertSame(
firstInvocation,
secondInvocation,
firstInvocation + " was not the same object as " + secondInvocation);
}
@Test
void testMult() {
// 92 per millisecond => 92,000 per second (base unit equivalent) => 5,520,000 per minute
var baseUnit = new ExampleUnit(92);
var vel = VelocityUnit.combine(baseUnit, Millisecond);
var mult = vel.mult(Minute);
assertEquals(1 / 92000.0, mult.fromBaseUnits(1), 1e-5);
assertEquals(5_520_000, mult.toBaseUnits(1), 1e-5);
}
}

View File

@@ -0,0 +1,22 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.units;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
class VoltageUnitTest {
@Test
void testVoltsTimesAmps() {
assertTrue(Units.Volts.mult(Units.Amps, "", "").equivalent(Units.Watts));
}
@Test
void testMilliVoltsTimesMilliAmps() {
// results in microwatts
assertTrue(Units.Millivolts.mult(Units.Milliamps, "", "").equivalent(Units.Micro(Units.Watts)));
}
}

View File

@@ -0,0 +1,96 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.units.collections;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
class LongToObjectHashMapTest {
@Test
void put() {
var map = new LongToObjectHashMap<String>();
assertEquals(0, map.size());
long key = 42;
var previousValue = map.put(key, "The Meaning of Life");
assertNull(previousValue);
assertEquals(1, map.size());
assertEquals("The Meaning of Life", map.get(key));
assertTrue(map.containsKey(key));
previousValue = map.put(key, "Addendum: Live Long and Prosper");
assertEquals("The Meaning of Life", previousValue);
assertEquals(1, map.size(), "The map should not have grown when changing the value for a key");
assertTrue(map.containsKey(key));
var removed = map.remove(key);
assertEquals("Addendum: Live Long and Prosper", removed);
assertEquals(0, map.size());
assertFalse(map.containsKey(key));
}
@Test
void testGrowth() {
var map = new LongToObjectHashMap<String>();
int numInserts = 8000;
for (int i = 0; i < numInserts; i++) {
map.put(i, "value-" + i);
}
assertEquals(numInserts, map.size());
assertEquals(16384, map.capacity());
for (int i = 0; i < numInserts; i++) {
assertEquals("value-" + i, map.get(i), "key " + i + " had an unexpected value");
assertTrue(map.containsKey(i));
}
for (int i = 0; i < numInserts; i++) {
map.remove(i);
}
// all items should have been removed
assertEquals(0, map.size());
// ... but the map shouldn't resize
assertEquals(16384, map.capacity());
}
@Test
void testClear() {
var map = new LongToObjectHashMap<>();
for (int i = 0; i < 10_000; i++) {
map.put(i, i * i);
}
assertEquals(10_000, map.size());
assertEquals(16384, map.capacity());
map.clear();
assertEquals(0, map.size());
assertEquals(16384, map.capacity());
map.clear(); // should be a NOP
assertEquals(0, map.size());
assertEquals(16384, map.capacity());
}
@Test
void testKeySet() {
var map = new LongToObjectHashMap<String>();
int numInserts = 8000;
for (int i = 0; i < numInserts; i++) {
map.put(i, "value-" + i);
}
var keySet = map.keySet();
assertEquals(map.size(), keySet.size());
for (int i = 0; i < numInserts; i++) {
assertTrue(keySet.contains(i), "keySet does not contain key " + i);
}
}
}

View File

@@ -0,0 +1,27 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.units.measure;
import static edu.wpi.first.units.Units.Milliseconds;
import static edu.wpi.first.units.Units.Seconds;
import static edu.wpi.first.units.Units.Volts;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import edu.wpi.first.units.Measure;
import edu.wpi.first.units.VelocityUnit;
import edu.wpi.first.units.VoltageUnit;
import org.junit.jupiter.api.Test;
class VelocityTest {
@Test
void velocityTimesTimeReturnsDivisor() {
var velocity = VelocityUnit.combine(Volts, Seconds).of(123);
var time = Milliseconds.of(100);
Measure<VoltageUnit> result = velocity.times(time);
// Compile-time test - would fail to compile if the return type was Mult or Measure<?>
assertInstanceOf(Voltage.class, result);
}
}