001// Copyright (c) FIRST and other WPILib contributors.
002// Open Source Software; you can modify and/or share it under the terms of
003// the WPILib BSD license file in the root directory of this project.
004
005package edu.wpi.first.units;
006
007import java.util.Locale;
008
009/** Contains a set of predefined units. */
010public final class Units {
011  private Units() {
012    // Prevent instantiation
013  }
014
015  // Pseudo-classes describing the more common units of measure.
016
017  @SuppressWarnings("rawtypes")
018  public static final Unit AnonymousBaseUnit = new Dimensionless(1, "<?>", "<?>");
019
020  // Distance
021  public static final Distance Meters = BaseUnits.Distance;
022  public static final Distance Millimeters = Milli(Meters, "Millimeter", "mm");
023  public static final Distance Centimeters =
024      derive(Meters).splitInto(100).named("Centimeter").symbol("cm").make();
025  public static final Distance Inches =
026      derive(Millimeters).aggregate(25.4).named("Inch").symbol("in").make();
027  public static final Distance Feet =
028      derive(Inches).aggregate(12).named("Foot").symbol("ft").make();
029
030  // Time
031  public static final Time Seconds = BaseUnits.Time;
032  public static final Time Second = Seconds; // singularized alias
033  public static final Time Milliseconds = Milli(Seconds);
034  public static final Time Millisecond = Milliseconds; // singularized alias
035  public static final Time Microseconds = Micro(Seconds);
036  public static final Time Microsecond = Microseconds; // singularized alias
037  public static final Time Minutes =
038      derive(Seconds).aggregate(60).named("Minute").symbol("min").make();
039  public static final Time Minute = Minutes; // singularized alias
040
041  // Angle
042  public static final Angle Radians = BaseUnits.Angle;
043  public static final Angle Revolutions = new Angle(2 * Math.PI, "Revolution", "R");
044  public static final Angle Rotations = new Angle(2 * Math.PI, "Rotation", "R"); // alias revolution
045  public static final Angle Degrees =
046      derive(Revolutions).splitInto(360).named("Degree").symbol("°").make();
047
048  // Velocity
049  public static final Velocity<Distance> MetersPerSecond = Meters.per(Second);
050  public static final Velocity<Distance> FeetPerSecond = Feet.per(Second);
051  public static final Velocity<Distance> InchesPerSecond = Inches.per(Second);
052
053  public static final Velocity<Angle> RevolutionsPerSecond = Revolutions.per(Second);
054  public static final Velocity<Angle> RotationsPerSecond = Rotations.per(Second);
055  public static final Velocity<Angle> RPM = Rotations.per(Minute);
056  public static final Velocity<Angle> RadiansPerSecond = Radians.per(Second);
057  public static final Velocity<Angle> DegreesPerSecond = Degrees.per(Second);
058
059  // Acceleration
060  public static final Velocity<Velocity<Distance>> MetersPerSecondPerSecond =
061      MetersPerSecond.per(Second);
062  public static final Velocity<Velocity<Distance>> Gs =
063      derive(MetersPerSecondPerSecond).aggregate(9.80665).named("G").symbol("G").make();
064
065  // Mass
066  public static final Mass Kilograms = BaseUnits.Mass;
067  public static final Mass Grams = Milli(Kilograms, "Gram", "g");
068  public static final Mass Pounds =
069      derive(Grams).aggregate(453.592).named("Pound").symbol("lb.").make();
070  public static final Mass Ounces =
071      derive(Pounds).splitInto(16).named("Ounce").symbol("oz.").make();
072
073  // Unitless
074  public static final Dimensionless Value = BaseUnits.Value;
075  public static final Dimensionless Percent =
076      derive(Value).splitInto(100).named("Percent").symbol("%").make();
077
078  // Voltage
079  public static final Voltage Volts = BaseUnits.Voltage;
080  public static final Voltage Millivolts = Milli(Volts);
081
082  // Current
083  public static final Current Amps = BaseUnits.Current;
084  public static final Current Milliamps = Milli(Amps);
085
086  // Energy
087  public static final Energy Joules = BaseUnits.Energy;
088  public static final Energy Millijoules = Milli(Joules);
089  public static final Energy Kilojoules = Kilo(Joules);
090
091  // Power
092  public static final Power Watts = BaseUnits.Power;
093  public static final Power Milliwatts = Milli(Watts);
094  public static final Power Horsepower =
095      derive(Watts).aggregate(745.7).named("Horsepower").symbol("HP").make();
096
097  // Temperature
098  public static final Temperature Kelvin = BaseUnits.Temperature;
099  public static final Temperature Celsius =
100      derive(Kelvin).offset(+273.15).named("Celsius").symbol("°C").make();
101
102  public static final Temperature Fahrenheit =
103      derive(Celsius)
104          .mappingInputRange(0, 100)
105          .toOutputRange(32, 212)
106          .named("Fahrenheit")
107          .symbol("°F")
108          .make();
109
110  // Standard feedforward units for kV and kA.
111  // kS and kG are just volts, which is already defined earlier
112  public static final Per<Voltage, Velocity<Distance>> VoltsPerMeterPerSecond =
113      Volts.per(MetersPerSecond);
114  public static final Per<Voltage, Velocity<Velocity<Distance>>> VoltsPerMeterPerSecondSquared =
115      Volts.per(MetersPerSecondPerSecond);
116
117  public static final Per<Voltage, Velocity<Angle>> VoltsPerRadianPerSecond =
118      Volts.per(RadiansPerSecond);
119  public static final Per<Voltage, Velocity<Velocity<Angle>>> VoltsPerRadianPerSecondSquared =
120      Volts.per(RadiansPerSecond.per(Second));
121
122  /**
123   * Creates a unit equal to a thousandth of the base unit, eg Milliseconds = Milli(Units.Seconds).
124   *
125   * @param <U> the type of the unit
126   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
127   * @param name the name of the new derived unit
128   * @param symbol the symbol of the new derived unit
129   * @return the milli-unit
130   */
131  @SuppressWarnings({"PMD.MethodName", "checkstyle:methodname"})
132  public static <U extends Unit<U>> U Milli(Unit<U> baseUnit, String name, String symbol) {
133    return derive(baseUnit).splitInto(1000).named(name).symbol(symbol).make();
134  }
135
136  /**
137   * Creates a unit equal to a thousandth of the base unit, eg Milliseconds = Milli(Units.Seconds).
138   *
139   * @param <U> the type of the unit
140   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
141   * @return the milli-unit
142   */
143  @SuppressWarnings({"PMD.MethodName", "checkstyle:methodname"})
144  public static <U extends Unit<U>> U Milli(Unit<U> baseUnit) {
145    return Milli(
146        baseUnit, "Milli" + baseUnit.name().toLowerCase(Locale.ROOT), "m" + baseUnit.symbol());
147  }
148
149  /**
150   * Creates a unit equal to a millionth of the base unit, eg {@code Microseconds =
151   * Micro(Units.Seconds, "Microseconds", 'us")}.
152   *
153   * @param <U> the type of the unit
154   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
155   * @param name the name of the new derived unit
156   * @param symbol the symbol of the new derived unit
157   * @return the micro-unit
158   */
159  @SuppressWarnings({"PMD.MethodName", "checkstyle:methodname"})
160  public static <U extends Unit<U>> U Micro(Unit<U> baseUnit, String name, String symbol) {
161    return derive(baseUnit).splitInto(1_000_000).named(name).symbol(symbol).make();
162  }
163
164  /**
165   * Creates a unit equal to a millionth of the base unit, eg Microseconds = Micro(Units.Seconds).
166   *
167   * @param <U> the type of the unit
168   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
169   * @return the micro-unit
170   */
171  @SuppressWarnings({"PMD.MethodName", "checkstyle:methodname"})
172  public static <U extends Unit<U>> U Micro(Unit<U> baseUnit) {
173    return Micro(
174        baseUnit, "Micro" + baseUnit.name().toLowerCase(Locale.ROOT), "u" + baseUnit.symbol());
175  }
176
177  /**
178   * Creates a unit equal to a thousand of the base unit, eg Kilograms = Kilo(Units.Grams).
179   *
180   * @param <U> the type of the unit
181   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
182   * @param name the name of the new derived unit
183   * @param symbol the symbol of the new derived unit
184   * @return the kilo-unit
185   */
186  @SuppressWarnings({"PMD.MethodName", "checkstyle:methodname"})
187  public static <U extends Unit<U>> U Kilo(Unit<U> baseUnit, String name, String symbol) {
188    return derive(baseUnit).aggregate(1000).named(name).symbol(symbol).make();
189  }
190
191  /**
192   * Creates a unit equal to a thousand of the base unit, eg Kilograms = Kilo(Units.Grams).
193   *
194   * @param <U> the type of the unit
195   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
196   * @return the kilo-unit
197   */
198  @SuppressWarnings({"PMD.MethodName", "checkstyle:methodname"})
199  public static <U extends Unit<U>> U Kilo(Unit<U> baseUnit) {
200    return Kilo(
201        baseUnit, "Kilo" + baseUnit.name().toLowerCase(Locale.ROOT), "K" + baseUnit.symbol());
202  }
203
204  @SuppressWarnings("unchecked")
205  public static <U extends Unit<U>> UnitBuilder<U> derive(Unit<U> unit) {
206    return new UnitBuilder<>((U) unit);
207  }
208
209  @SuppressWarnings("unchecked")
210  public static <U extends Unit<U>> U anonymous() {
211    return (U) AnonymousBaseUnit;
212  }
213}