mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
To reduce the need for users to manually perform unit conversions, this allows Measure objects from wpiunits to be passed into most places in wpimath that currently expect doubles in terms of SI units like meters. For example, users would need to know that unit conversion is required - and what the correct units are. Using units would be more difficult to write code for than just hardcoding a value or using Units.inchesToMeters. Now, using units has no more developer overhead than using raw numbers.
350 lines
11 KiB
Java
350 lines
11 KiB
Java
// 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 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);
|
|
}
|
|
|
|
// Distances
|
|
|
|
@Test
|
|
void testMeters() {
|
|
testBaseUnit(Meters);
|
|
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);
|
|
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);
|
|
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(Units.AnonymousBaseUnit, Gs.getUnit());
|
|
assertEquals(Seconds, Gs.getPeriod());
|
|
}
|
|
|
|
// Time
|
|
|
|
@Test
|
|
void testSeconds() {
|
|
testBaseUnit(Seconds);
|
|
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);
|
|
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);
|
|
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);
|
|
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);
|
|
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);
|
|
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);
|
|
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);
|
|
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);
|
|
}
|
|
}
|