mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-25 01:41:43 +00:00
[wpiunits] Java units API rewrite (#6958)
Java generics are too limited to do what we need. This refactors generic code previously in Unit and Measure into unit-specific classes that can have unit-safe math operations (notably, times and divide) that can return values in known units instead of a wildcarded Measure<?>. Unit-specific measure implementations are automatically generated by ./wpiunits/generate_units.py, which generates generic interfaces and mutable and immutable implementations of those interfaces. These make up the bulk of the diff of this PR (approximately 9300 LOC). This also adds units for angular and linear velocities, accelerations, and momenta; moment of inertia; and torque.
This commit is contained in:
@@ -4,14 +4,15 @@
|
||||
|
||||
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 CurrentTest {
|
||||
class CurrentUnitTest {
|
||||
@Test
|
||||
void testAmpsTimesVolts() {
|
||||
Power combined = Units.Amps.times(Units.Volts, "Watt", "w");
|
||||
PowerUnit combined = Units.Amps.mult(Units.Volts, "Watt", "w");
|
||||
|
||||
assertTrue(combined.equivalent(Units.Watts));
|
||||
}
|
||||
@@ -19,8 +20,11 @@ class CurrentTest {
|
||||
@Test
|
||||
void testMilliAmpsTimesMilliVolts() {
|
||||
// results in microwatts
|
||||
assertTrue(
|
||||
Units.Milliamps.times(Units.Millivolts, "Microwatt", "uW")
|
||||
.equivalent(Units.Milli(Units.Milliwatts)));
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -9,18 +9,18 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class DistanceTest {
|
||||
class DistanceUnitTest {
|
||||
@Test
|
||||
void testBaseUnitDistancePerTime() {
|
||||
Velocity<Distance> anonBaseUnit =
|
||||
new Distance(null, 1, "D", "d").per(new Time(null, 1, "T", "t"));
|
||||
LinearVelocityUnit anonBaseUnit =
|
||||
new DistanceUnit(null, 1, "D", "d").per(new TimeUnit(null, 1, "T", "t"));
|
||||
|
||||
assertTrue(Units.MetersPerSecond.equivalent(anonBaseUnit));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFeetPerSecond() {
|
||||
Velocity<Distance> feetPerMillisecond = Units.Feet.per(Units.Milliseconds);
|
||||
LinearVelocityUnit feetPerMillisecond = Units.Feet.per(Units.Milliseconds);
|
||||
|
||||
// one foot per millisecond
|
||||
// = (1 / 3.28084) meters per (1 / 1000) seconds
|
||||
@@ -1,91 +0,0 @@
|
||||
// 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.Inches;
|
||||
import static edu.wpi.first.units.Units.Revolutions;
|
||||
import static edu.wpi.first.units.Units.Second;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class EncoderTest {
|
||||
static class Encoder<U extends Unit<U>> {
|
||||
int m_ticks; // = 0
|
||||
private Measure<U> m_distancePerPulse;
|
||||
private MutableMeasure<U> m_distance;
|
||||
private MutableMeasure<Velocity<U>> m_rate;
|
||||
|
||||
void setDistancePerPulse(Measure<U> distancePerPulse) {
|
||||
m_distancePerPulse = distancePerPulse;
|
||||
m_distance = MutableMeasure.zero(distancePerPulse.unit());
|
||||
m_rate = MutableMeasure.zero(distancePerPulse.unit().per(Second));
|
||||
}
|
||||
|
||||
Measure<U> getDistance() {
|
||||
return m_distance;
|
||||
}
|
||||
|
||||
Measure<Velocity<U>> getRate() {
|
||||
return m_rate;
|
||||
}
|
||||
|
||||
void setTicks(int ticks) {
|
||||
// pretend we read from JNI here instead of being passed a specific value
|
||||
var change = ticks - m_ticks;
|
||||
m_ticks = ticks;
|
||||
m_distance.mut_setMagnitude(m_distancePerPulse.magnitude() * ticks);
|
||||
|
||||
// assumes the last update was 1 second ago - fine for tests
|
||||
m_rate.mut_setMagnitude(m_distancePerPulse.magnitude() * change);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAsDistance() {
|
||||
double ticksPerRevolution = 2048;
|
||||
|
||||
var encoder = new Encoder<Distance>();
|
||||
|
||||
// distance per rotation = (wheel circumference / gear ratio)
|
||||
// distance per tick = distance per rotation / ticks per rotation
|
||||
var wheelDiameter = Inches.of(6);
|
||||
double gearRatio = 10; // 10:1 ratio
|
||||
Measure<Distance> distancePerPulse =
|
||||
wheelDiameter.times(Math.PI).divide(gearRatio).divide(ticksPerRevolution);
|
||||
encoder.setDistancePerPulse(distancePerPulse);
|
||||
|
||||
encoder.m_ticks = 0;
|
||||
assertEquals(0, encoder.getDistance().in(Inches), Measure.EQUIVALENCE_THRESHOLD);
|
||||
assertEquals(0, encoder.getRate().in(Inches.per(Second)), Measure.EQUIVALENCE_THRESHOLD);
|
||||
|
||||
// one full encoder turn, 1/10th of a wheel rotation
|
||||
encoder.setTicks(2048);
|
||||
assertEquals(6 * Math.PI / 10, encoder.getDistance().in(Inches), Measure.EQUIVALENCE_THRESHOLD);
|
||||
|
||||
// one full encoder turn back, 1/10th of a wheel rotation - rate should be negative
|
||||
encoder.setTicks(0);
|
||||
assertEquals(
|
||||
-6 * Math.PI / 10, encoder.getRate().in(Inches.per(Second)), Measure.EQUIVALENCE_THRESHOLD);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAsRevolutions() {
|
||||
double ticksPerRevolution = 2048;
|
||||
|
||||
var encoder = new Encoder<Angle>();
|
||||
|
||||
Measure<Angle> distancePerPulse = Revolutions.of(1).divide(ticksPerRevolution);
|
||||
encoder.setDistancePerPulse(distancePerPulse);
|
||||
|
||||
encoder.m_ticks = 0;
|
||||
assertEquals(0, encoder.getDistance().in(Revolutions), Measure.EQUIVALENCE_THRESHOLD);
|
||||
assertEquals(0, encoder.getRate().in(Revolutions.per(Second)), Measure.EQUIVALENCE_THRESHOLD);
|
||||
|
||||
encoder.setTicks(2048); // one full encoder turn, 1/10th of a wheel rotation
|
||||
assertEquals(1, encoder.getDistance().in(Revolutions), Measure.EQUIVALENCE_THRESHOLD);
|
||||
assertEquals(1, encoder.getRate().in(Revolutions.per(Second)), Measure.EQUIVALENCE_THRESHOLD);
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
package edu.wpi.first.units;
|
||||
|
||||
class ExampleUnit extends Unit<ExampleUnit> {
|
||||
import edu.wpi.first.units.mutable.GenericMutableMeasureImpl;
|
||||
|
||||
class ExampleUnit extends Unit {
|
||||
ExampleUnit(double baseUnitEquivalent) {
|
||||
this(baseUnitEquivalent, "Example", "ex");
|
||||
}
|
||||
@@ -21,4 +23,28 @@ class ExampleUnit extends Unit<ExampleUnit> {
|
||||
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 MutableMeasure<ExampleUnit, ?, ?> mutable(double initialMagnitude) {
|
||||
return new GenericMutableMeasureImpl<>(initialMagnitude, toBaseUnits(initialMagnitude), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VelocityUnit<ExampleUnit> per(TimeUnit time) {
|
||||
return VelocityUnit.combine(this, time);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,69 +11,106 @@ 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() {
|
||||
Unit<Distance> unit = Units.Feet;
|
||||
DistanceUnit unit = Units.Feet;
|
||||
double magnitude = 10;
|
||||
Measure<Distance> m = unit.of(magnitude);
|
||||
Distance m = unit.of(magnitude);
|
||||
assertEquals(unit, m.unit(), "Wrong units");
|
||||
assertEquals(magnitude, m.magnitude(), 0, "Wrong magnitude");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMultiply() {
|
||||
Measure<Distance> m = Units.Feet.of(1);
|
||||
Measure<Distance> m2 = m.times(10);
|
||||
assertEquals(10, m2.magnitude(), 1e-12);
|
||||
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).divide(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).divide(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() {
|
||||
Measure<Distance> m = Units.Meters.of(1);
|
||||
Measure<Distance> m2 = m.divide(10);
|
||||
Distance m = Units.Meters.of(1);
|
||||
Distance m2 = m.divide(10);
|
||||
assertEquals(0.1, m2.magnitude(), 0);
|
||||
assertNotSame(m2, m);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAdd() {
|
||||
Measure<Distance> m1 = Units.Feet.of(1);
|
||||
Measure<Distance> m2 = Units.Inches.of(2);
|
||||
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() {
|
||||
Measure<Distance> m1 = Units.Feet.of(1);
|
||||
Measure<Distance> m2 = Units.Inches.of(2);
|
||||
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 testNegate() {
|
||||
Measure<Distance> m = Units.Feet.of(123);
|
||||
Measure<Distance> n = m.negate();
|
||||
assertEquals(-m.magnitude(), n.magnitude(), 1e-12);
|
||||
assertEquals(m.unit(), n.unit());
|
||||
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() {
|
||||
Measure<Distance> inches = Units.Inches.of(12);
|
||||
Measure<Distance> feet = Units.Feet.of(1);
|
||||
Distance inches = Units.Inches.of(12);
|
||||
Distance feet = Units.Feet.of(1);
|
||||
assertTrue(inches.isEquivalent(feet));
|
||||
assertTrue(feet.isEquivalent(inches));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAs() {
|
||||
Measure<Distance> m = Units.Inches.of(12);
|
||||
Distance m = Units.Inches.of(12);
|
||||
assertEquals(1, m.in(Units.Feet), Measure.EQUIVALENCE_THRESHOLD);
|
||||
}
|
||||
|
||||
@@ -84,7 +121,7 @@ class MeasureTest {
|
||||
|
||||
// 144 Kg / (53 ms) = (1000 / 53) * 144 Kg/s = (144,000 / 53) Kg/s
|
||||
|
||||
var result = measure.per(dt);
|
||||
var result = measure.divide(dt);
|
||||
assertEquals(144_000.0 / 53, result.baseUnitMagnitude(), 1e-5);
|
||||
assertEquals(Units.Kilograms.per(Units.Milliseconds), result.unit());
|
||||
}
|
||||
@@ -94,106 +131,33 @@ class MeasureTest {
|
||||
var measure = Units.Kilograms.of(144);
|
||||
var result = measure.per(Units.Millisecond);
|
||||
|
||||
assertEquals(Velocity.class, result.unit().getClass());
|
||||
assertEquals(VelocityUnit.class, result.unit().getClass());
|
||||
assertEquals(144_000.0, result.baseUnitMagnitude(), 1e-5);
|
||||
assertEquals(Units.Kilograms.per(Units.Milliseconds), result.unit());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTimesMeasure() {
|
||||
var m1 = Units.Volts.of(1.567);
|
||||
var m2 = Units.Kilograms.of(8.4e-5);
|
||||
|
||||
assertEquals(Units.Volts.mult(Units.Kilograms).of(1.567 * 8.4e-5), m1.times(m2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTimesUnitless() {
|
||||
var unit = new ExampleUnit(6);
|
||||
var measure = unit.of(2.5);
|
||||
var multiplier = Units.Percent.of(125); // 125% or 1.25x
|
||||
Measure<?> result = measure.times(multiplier);
|
||||
assertSame(unit, result.unit());
|
||||
|
||||
assertEquals(2.5 * 1.25, result.magnitude());
|
||||
assertEquals(2.5 * 1.25 * 6, result.baseUnitMagnitude());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTimesPerWithDimensionalAnalysis() {
|
||||
var measureA = Units.Feet.of(62); // 62 feet
|
||||
var measureB = Units.Radians.of(6).per(Units.Inches); // 6 radians per inch
|
||||
Measure<?> aTimesB = measureA.times(measureB); // (62 feet) * (6 rad/inch) = 4464 rad
|
||||
assertEquals(Units.Radians, aTimesB.unit());
|
||||
assertEquals(4464, aTimesB.magnitude(), 1e-12);
|
||||
|
||||
Measure<?> bTimesA = measureB.times(measureA); // should be identical to the above
|
||||
assertTrue(bTimesA.isEquivalent(aTimesB));
|
||||
assertTrue(aTimesB.isEquivalent(bTimesA));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPerTimesPerWithDimensionalAnalysis() {
|
||||
var measureA = Units.Inches.of(16).per(Units.Volts);
|
||||
var measureB = Units.Millivolts.of(14).per(Units.Meters);
|
||||
Measure<?> aTimesB = measureA.times(measureB);
|
||||
assertEquals(Units.Value, aTimesB.unit());
|
||||
assertEquals((16 * 25.4 / 1000) * (14 / 1000.0), aTimesB.magnitude());
|
||||
assertEquals((16 * 25.4 / 1000) * (14 / 1000.0), aTimesB.baseUnitMagnitude());
|
||||
|
||||
Measure<?> bTimesA = measureB.times(measureA); // should be identical to the above
|
||||
assertTrue(bTimesA.isEquivalent(aTimesB));
|
||||
assertTrue(aTimesB.isEquivalent(bTimesA));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPerTimesMeasure() {
|
||||
var m1 = Units.Feet.per(Units.Milliseconds).of(19);
|
||||
var m2 = Units.Seconds.of(44);
|
||||
|
||||
// 19 ft/ms = 19,000 ft/s
|
||||
// 19,000 ft/s * 44s = 836,000 ft
|
||||
assertTrue(Units.Feet.of(836_000).isNear(m1.times(m2), 1e-12));
|
||||
|
||||
// 42 ex per foot * 17mm = 42 ex * 17mm / (304.8mm/ft) = 42 * 17 / 304.8 = 2.34252
|
||||
var exampleUnit = new ExampleUnit(1);
|
||||
var m3 = exampleUnit.per(Units.Feet).of(42);
|
||||
var m4 = Units.Millimeters.of(17);
|
||||
assertEquals(exampleUnit.of(42 * 17 / (12 * 25.4)), m3.times(m4));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDivideMeasure() {
|
||||
// Dimensionless divide
|
||||
var m1 = Units.Meters.of(6);
|
||||
var m2 = Units.Value.of(3);
|
||||
var result = m1.divide(m2);
|
||||
assertEquals(m1.divide(m2).magnitude(), 2);
|
||||
assertEquals(result.unit(), Units.Meters);
|
||||
assertEquals(2, m1.divide(m2).magnitude());
|
||||
assertEquals(Units.Meters, result.unit());
|
||||
// Velocity divide
|
||||
var m3 = Units.Meters.of(8);
|
||||
var m4 = Units.Meters.per(Units.Second).of(4);
|
||||
result = m3.divide(m4);
|
||||
assertEquals(result.magnitude(), 2);
|
||||
assertEquals(result.unit(), Units.Second);
|
||||
// Per divide
|
||||
var time = m3.divide(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);
|
||||
result = m5.divide(m6);
|
||||
assertEquals(result.magnitude(), 3);
|
||||
assertEquals(result.unit(), Units.Meter);
|
||||
// Fallthrough divide
|
||||
var m7 = Units.Seconds.of(10);
|
||||
var m8 = Units.Amps.of(2);
|
||||
result = m7.divide(m8);
|
||||
assertEquals(result.magnitude(), 5);
|
||||
assertEquals(result.unit(), Units.Seconds.per(Units.Amps));
|
||||
// Same base unit divide
|
||||
var m9 = Units.Meters.of(8);
|
||||
var m10 = Units.Meters.of(4);
|
||||
result = m9.divide(m10);
|
||||
assertEquals(result.magnitude(), 2);
|
||||
assertEquals(result.unit(), Units.Value);
|
||||
|
||||
// Voltage/(Voltage/Distance) -> Voltage * Distance/Voltage -> Distance
|
||||
var dist = m5.divide(m6);
|
||||
assertEquals(3, dist.magnitude());
|
||||
assertEquals(Units.Meter, dist.unit());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -249,57 +213,6 @@ class MeasureTest {
|
||||
assertFalse(base.gt(base));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTimesScalar() {
|
||||
var unit = new ExampleUnit(42);
|
||||
var measure = unit.of(4.2);
|
||||
var scalar = 18;
|
||||
var result = measure.times(scalar);
|
||||
assertNotSame(measure, result);
|
||||
assertSame(unit, result.unit());
|
||||
assertEquals(4.2 * 18, result.magnitude());
|
||||
assertEquals(4.2 * 42 * 18, result.baseUnitMagnitude());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPerUnit() {
|
||||
var unitA = new ExampleUnit(10);
|
||||
var unitB = new ExampleUnit(12);
|
||||
var measure = unitA.of(1.2);
|
||||
var result = measure.per(unitB);
|
||||
assertEquals(Per.combine(unitA, unitB), result.unit()); // A/B has base equivalent of 10/12
|
||||
assertEquals(1, result.baseUnitMagnitude()); // 10/12 * 12/10 = 1
|
||||
assertEquals(measure.magnitude(), result.magnitude());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddMeasureSameUnit() {
|
||||
var unit = new ExampleUnit(8.2);
|
||||
var measureA = unit.of(3.1);
|
||||
var measureB = unit.of(91.6);
|
||||
var result = measureA.plus(measureB);
|
||||
assertEquals(unit, result.unit());
|
||||
assertEquals(94.7, result.magnitude(), 1e-12);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddMeasuresDifferentUnits() {
|
||||
var unitA = new ExampleUnit(8.2);
|
||||
var unitB = new ExampleUnit(7.3);
|
||||
var measureA = unitA.of(5);
|
||||
var measureB = unitB.of(16);
|
||||
var aPlusB = measureA.plus(measureB);
|
||||
|
||||
assertEquals(unitA, aPlusB.unit());
|
||||
assertEquals(8.2 * 5 + 7.3 * 16, aPlusB.baseUnitMagnitude(), 1e-12);
|
||||
assertEquals(5 + (16 * 7.3 / 8.2), aPlusB.magnitude(), 1e-12);
|
||||
|
||||
var bPlusA = measureB.plus(measureA);
|
||||
assertEquals(unitB, bPlusA.unit());
|
||||
assertEquals(8.2 * 5 + 7.3 * 16, bPlusA.baseUnitMagnitude(), 1e-12);
|
||||
assertEquals(16 + (5 * 8.2 / 7.3), bPlusA.magnitude(), 1e-12);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMinNoArgs() {
|
||||
var min = Measure.min();
|
||||
@@ -388,29 +301,29 @@ class MeasureTest {
|
||||
assertTrue(measureCompared.isNear(measureComparing, Units.Millimeters.of(300)));
|
||||
assertFalse(measureCompared.isNear(measureComparing, Units.Centimeters.of(10)));
|
||||
|
||||
measureCompared = measureCompared.negate();
|
||||
measureComparing = measureComparing.negate();
|
||||
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.negate();
|
||||
measureComparing = measureComparing.negate();
|
||||
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.negate();
|
||||
measureComparing = measureComparing.negate();
|
||||
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.negate();
|
||||
measureComparing = measureComparing.negate();
|
||||
measureCompared = measureCompared.unaryMinus();
|
||||
measureComparing = measureComparing.unaryMinus();
|
||||
|
||||
// Tolerance exact difference between measures.
|
||||
assertTrue(measureCompared.isNear(measureComparing, Units.Millimeters.of(200)));
|
||||
|
||||
@@ -9,12 +9,12 @@ import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class MultTest {
|
||||
class MultUnitTest {
|
||||
@Test
|
||||
void testAutomaticNames() {
|
||||
var unitA = new ExampleUnit(1, "Ay", "a");
|
||||
var unitB = new ExampleUnit(1, "Bee", "b");
|
||||
var mult = Mult.combine(unitA, unitB);
|
||||
var mult = MultUnit.combine(unitA, unitB);
|
||||
assertEquals("Ay-Bee", mult.name());
|
||||
assertEquals("a*b", mult.symbol());
|
||||
}
|
||||
@@ -23,7 +23,7 @@ class MultTest {
|
||||
void testCombine() {
|
||||
var unitA = new ExampleUnit(100);
|
||||
var unitB = new ExampleUnit(0.912);
|
||||
var mult = Mult.combine(unitA, unitB);
|
||||
var mult = MultUnit.combine(unitA, unitB);
|
||||
assertEquals(91.2, mult.toBaseUnits(1));
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class MultTest {
|
||||
void testCaches() {
|
||||
var unitA = new ExampleUnit(1);
|
||||
var unitB = new ExampleUnit(2);
|
||||
var mult = Mult.combine(unitA, unitB);
|
||||
assertSame(mult, Mult.combine(unitA, unitB));
|
||||
var mult = MultUnit.combine(unitA, unitB);
|
||||
assertSame(mult, MultUnit.combine(unitA, unitB));
|
||||
}
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
// 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.Centimeters;
|
||||
import static edu.wpi.first.units.Units.FeetPerSecond;
|
||||
import static edu.wpi.first.units.Units.InchesPerSecond;
|
||||
import static edu.wpi.first.units.Units.Meters;
|
||||
import static edu.wpi.first.units.Units.Millisecond;
|
||||
import static edu.wpi.first.units.Units.Millivolts;
|
||||
import static edu.wpi.first.units.Units.Second;
|
||||
import static edu.wpi.first.units.Units.Volts;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class MutableMeasureTest {
|
||||
@Test
|
||||
void testWrapper() {
|
||||
var unit = new ExampleUnit(1);
|
||||
var measure = unit.of(1234);
|
||||
var mutable = MutableMeasure.mutable(measure);
|
||||
assertEquals(measure.magnitude(), mutable.magnitude(), 0);
|
||||
assertEquals(measure.unit(), mutable.unit());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetMagnitude() {
|
||||
var measure = MutableMeasure.ofRelativeUnits(0, FeetPerSecond);
|
||||
double newMagnitude = 48.123;
|
||||
measure.mut_setMagnitude(newMagnitude);
|
||||
assertEquals(newMagnitude, measure.magnitude(), 0); // should be an exact match
|
||||
double feetToMeters = 0.3048;
|
||||
assertEquals(newMagnitude * feetToMeters, measure.baseUnitMagnitude(), 1e-12);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMut_times() {
|
||||
var measure = MutableMeasure.ofRelativeUnits(18, FeetPerSecond);
|
||||
double scalar = Math.PI;
|
||||
var result = measure.mut_times(scalar);
|
||||
assertSame(measure, result, "mut_times should return the same object");
|
||||
assertEquals(18 * Math.PI, measure.magnitude(), 1e-12);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMut_divide() {
|
||||
var measure = MutableMeasure.ofRelativeUnits(18, FeetPerSecond);
|
||||
double scalar = Math.PI;
|
||||
var result = measure.mut_divide(scalar);
|
||||
assertSame(measure, result, "mut_times should return the same object");
|
||||
assertEquals(18 / Math.PI, measure.magnitude(), 1e-12);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReplaceMeasure() {
|
||||
var measure = MutableMeasure.ofRelativeUnits(17.6, FeetPerSecond);
|
||||
var replacer = Meters.per(Millisecond).of(94.872);
|
||||
var result = measure.mut_replace(replacer);
|
||||
assertSame(measure, result, "Replacing should return the mutable measure");
|
||||
assertSame(replacer.unit(), measure.unit());
|
||||
assertEquals(replacer.magnitude(), measure.magnitude(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReplaceRaw() {
|
||||
var measure = MutableMeasure.ofRelativeUnits(-542, FeetPerSecond);
|
||||
var result = measure.mut_replace(62, Meters.per(Millisecond));
|
||||
assertSame(measure, result, "Replacing should return the mutable measure");
|
||||
assertSame(Meters.per(Millisecond), measure.unit());
|
||||
assertEquals(62, measure.magnitude(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAccMeasure() {
|
||||
var measure = MutableMeasure.ofRelativeUnits(8.5431, FeetPerSecond);
|
||||
var acc = Meters.per(Millisecond).of(-23.62);
|
||||
var result = measure.mut_acc(acc);
|
||||
assertSame(measure, result, "Acc should return the mutable measure");
|
||||
assertSame(FeetPerSecond, measure.unit(), "Unit shouldn't change");
|
||||
assertEquals(8.5431 - (23.62 * (1 / 0.3048) * 1000), measure.magnitude(), 1e-10);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAccRaw() {
|
||||
var measure = MutableMeasure.ofRelativeUnits(99.999999, FeetPerSecond);
|
||||
var result = measure.mut_acc(22.981);
|
||||
assertSame(measure, result);
|
||||
assertSame(FeetPerSecond, measure.unit());
|
||||
assertEquals(122.980999, measure.magnitude(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMutPlusMeasure() {
|
||||
var measure = MutableMeasure.ofRelativeUnits(400, InchesPerSecond);
|
||||
var other = Centimeters.per(Second).of(41.312);
|
||||
var result = measure.mut_plus(other);
|
||||
assertSame(measure, result);
|
||||
assertSame(InchesPerSecond, result.unit());
|
||||
assertEquals(416.2645669291339, measure.magnitude(), 1e-12);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMutPlusRaw() {
|
||||
var measure = MutableMeasure.ofRelativeUnits(31.51, Volts);
|
||||
var result = measure.mut_plus(66.641, Millivolts);
|
||||
assertSame(measure, result);
|
||||
assertSame(Volts, result.unit());
|
||||
assertEquals(31.576641, result.magnitude(), 1e-10);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMutMinusMeasure() {
|
||||
var measure = MutableMeasure.ofRelativeUnits(400, InchesPerSecond);
|
||||
var other = Centimeters.per(Second).of(41.312);
|
||||
var result = measure.mut_minus(other);
|
||||
assertSame(measure, result);
|
||||
assertSame(InchesPerSecond, result.unit());
|
||||
assertEquals(383.7354330708662, measure.magnitude(), 1e-12);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMutMinusRaw() {
|
||||
var measure = MutableMeasure.ofRelativeUnits(31.51, Volts);
|
||||
var result = measure.mut_minus(66.641, Millivolts);
|
||||
assertSame(measure, result);
|
||||
assertSame(Volts, result.unit());
|
||||
assertEquals(31.443359, result.magnitude(), 1e-10);
|
||||
}
|
||||
}
|
||||
56
wpiunits/src/test/java/edu/wpi/first/units/PerUnitTest.java
Normal file
56
wpiunits/src/test/java/edu/wpi/first/units/PerUnitTest.java
Normal 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());
|
||||
}
|
||||
}
|
||||
@@ -42,27 +42,28 @@ 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(Unit<?> baseUnit) {
|
||||
assertEquals(0, baseUnit.of(0).baseUnitMagnitude(), 0);
|
||||
assertEquals(1, baseUnit.of(1).baseUnitMagnitude(), 0);
|
||||
assertEquals(-1, baseUnit.of(-1).baseUnitMagnitude(), 0);
|
||||
assertEquals(100, baseUnit.of(100).baseUnitMagnitude(), 0);
|
||||
assertEquals(8.281723, baseUnit.of(8.281723).baseUnitMagnitude(), 0);
|
||||
assertEquals(Float.MAX_VALUE, baseUnit.of(Float.MAX_VALUE).baseUnitMagnitude(), 0);
|
||||
assertEquals(Float.MIN_VALUE, baseUnit.of(Float.MIN_VALUE).baseUnitMagnitude(), 0);
|
||||
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);
|
||||
testBaseUnit(Meters::of);
|
||||
assertEquals("Meter", Meters.name());
|
||||
assertEquals("m", Meters.symbol());
|
||||
}
|
||||
@@ -105,7 +106,7 @@ class UnitsTest {
|
||||
|
||||
@Test
|
||||
void testMetersPerSecond() {
|
||||
testBaseUnit(MetersPerSecond);
|
||||
testBaseUnit(MetersPerSecond::of);
|
||||
assertEquals("Meter per Second", MetersPerSecond.name());
|
||||
assertEquals("m/s", MetersPerSecond.symbol());
|
||||
}
|
||||
@@ -122,7 +123,7 @@ class UnitsTest {
|
||||
|
||||
@Test
|
||||
void testMetersPerSecondPerSecond() {
|
||||
testBaseUnit(MetersPerSecondPerSecond);
|
||||
testBaseUnit(MetersPerSecondPerSecond::of);
|
||||
assertEquals("Meter per Second per Second", MetersPerSecondPerSecond.name());
|
||||
assertEquals("m/s/s", MetersPerSecondPerSecond.symbol());
|
||||
assertEquals(MetersPerSecond, MetersPerSecondPerSecond.getUnit());
|
||||
@@ -143,7 +144,7 @@ class UnitsTest {
|
||||
|
||||
@Test
|
||||
void testSeconds() {
|
||||
testBaseUnit(Seconds);
|
||||
testBaseUnit(Seconds::of);
|
||||
assertEquals("Second", Seconds.name());
|
||||
assertEquals("s", Seconds.symbol());
|
||||
}
|
||||
@@ -173,7 +174,7 @@ class UnitsTest {
|
||||
|
||||
@Test
|
||||
void testKilograms() {
|
||||
testBaseUnit(Kilograms);
|
||||
testBaseUnit(Kilograms::of);
|
||||
assertEquals("Kilogram", Kilograms.name());
|
||||
assertEquals("Kg", Kilograms.symbol());
|
||||
}
|
||||
@@ -210,7 +211,7 @@ class UnitsTest {
|
||||
|
||||
@Test
|
||||
void testRadians() {
|
||||
testBaseUnit(Radians);
|
||||
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());
|
||||
@@ -229,7 +230,7 @@ class UnitsTest {
|
||||
|
||||
@Test
|
||||
void testValue() {
|
||||
testBaseUnit(Value);
|
||||
testBaseUnit(Value::of);
|
||||
assertEquals("<?>", Value.name());
|
||||
assertEquals("<?>", Value.symbol());
|
||||
}
|
||||
@@ -245,7 +246,7 @@ class UnitsTest {
|
||||
|
||||
@Test
|
||||
void testVolts() {
|
||||
testBaseUnit(Volts);
|
||||
testBaseUnit(Volts::of);
|
||||
assertEquals("Volt", Volts.name());
|
||||
assertEquals("V", Volts.symbol());
|
||||
}
|
||||
@@ -261,7 +262,7 @@ class UnitsTest {
|
||||
|
||||
@Test
|
||||
void testAmps() {
|
||||
testBaseUnit(Amps);
|
||||
testBaseUnit(Amps::of);
|
||||
assertEquals("Amp", Amps.name());
|
||||
assertEquals("A", Amps.symbol());
|
||||
}
|
||||
@@ -277,7 +278,7 @@ class UnitsTest {
|
||||
|
||||
@Test
|
||||
void testWatts() {
|
||||
testBaseUnit(Watts);
|
||||
testBaseUnit(Watts::of);
|
||||
assertEquals("Watt", Watts.name());
|
||||
assertEquals("W", Watts.symbol());
|
||||
}
|
||||
@@ -300,7 +301,7 @@ class UnitsTest {
|
||||
|
||||
@Test
|
||||
void testKelvin() {
|
||||
testBaseUnit(Kelvin);
|
||||
testBaseUnit(Kelvin::of);
|
||||
assertEquals("Kelvin", Kelvin.name());
|
||||
assertEquals("K", Kelvin.symbol()); // note: there's no degree symbol for Kelvin!
|
||||
}
|
||||
|
||||
@@ -10,14 +10,17 @@ 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 VelocityTest {
|
||||
class VelocityUnitTest {
|
||||
@Test
|
||||
void testBaseUnit() {
|
||||
assertTrue(MetersPerSecond.equivalent(MetersPerSecond));
|
||||
@@ -26,7 +29,7 @@ class VelocityTest {
|
||||
|
||||
@Test
|
||||
void testToAcceleration() {
|
||||
Velocity<Velocity<Distance>> metersPerSecondPerMillisecond = MetersPerSecond.per(Millisecond);
|
||||
LinearAccelerationUnit metersPerSecondPerMillisecond = MetersPerSecond.per(Millisecond);
|
||||
|
||||
assertEquals(1000, metersPerSecondPerMillisecond.of(1).in(MetersPerSecondPerSecond), 0);
|
||||
assertEquals(0, metersPerSecondPerMillisecond.of(0).in(MetersPerSecondPerSecond), 0);
|
||||
@@ -38,8 +41,8 @@ class VelocityTest {
|
||||
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 ExampleUnit(5);
|
||||
var someTime = new ExampleUnit(600);
|
||||
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(
|
||||
@@ -50,9 +53,11 @@ class VelocityTest {
|
||||
|
||||
@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 = baseUnit.per(Millisecond);
|
||||
var mult = vel.mult(Second);
|
||||
assertEquals(92_000, mult.toBaseUnits(1), 1e-5);
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -8,16 +8,15 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class VoltageTest {
|
||||
class VoltageUnitTest {
|
||||
@Test
|
||||
void testVoltsTimesAmps() {
|
||||
assertTrue(Units.Volts.times(Units.Amps, "", "").equivalent(Units.Watts));
|
||||
assertTrue(Units.Volts.mult(Units.Amps, "", "").equivalent(Units.Watts));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMilliVoltsTimesMilliAmps() {
|
||||
// results in microwatts
|
||||
assertTrue(
|
||||
Units.Millivolts.times(Units.Milliamps, "", "").equivalent(Units.Milli(Units.Milliwatts)));
|
||||
assertTrue(Units.Millivolts.mult(Units.Milliamps, "", "").equivalent(Units.Micro(Units.Watts)));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user