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  /**
018   * Used as an internal placeholder value when a specific unit type cannot be determined. Do not
019   * use this directly.
020   */
021  @SuppressWarnings("rawtypes")
022  public static final Unit AnonymousBaseUnit = new Dimensionless(1, "<?>", "<?>");
023
024  // Distance
025  /** The base unit of distance. */
026  public static final Distance Meters = BaseUnits.Distance;
027
028  /** The base unit of distance. */
029  public static final Distance Meter = Meters; // alias
030
031  /** 1/1000 of a {@link #Meter}. */
032  public static final Distance Millimeters = Milli(Meters, "Millimeter", "mm");
033
034  /** 1/1000 of a {@link #Meter}. */
035  public static final Distance Millimeter = Millimeters; // alias
036
037  /** 1/100 of a {@link #Meter}. */
038  public static final Distance Centimeters =
039      derive(Meters).splitInto(100).named("Centimeter").symbol("cm").make();
040
041  /** 1/100 of a {@link #Meter}. */
042  public static final Distance Centimeter = Centimeters; // alias
043
044  /** 25.4/1000 of a {@link #Meter} and 1/12 of a {@link #Foot}. */
045  public static final Distance Inches =
046      derive(Millimeters).aggregate(25.4).named("Inch").symbol("in").make();
047
048  /** 25.4/1000 of a {@link #Meter} and 1/12 of a {@link #Foot}. */
049  public static final Distance Inch = Inches; // alias
050
051  /** 304.8/1000 of a {@link #Meter}, or 12 {@link #Inches}. */
052  public static final Distance Feet =
053      derive(Inches).aggregate(12).named("Foot").symbol("ft").make();
054
055  /** 304.8/1000 of a {@link #Meter}, or 12 {@link #Inches}. */
056  public static final Distance Foot = Feet; // alias
057
058  // Time
059  /** The base unit of time. */
060  public static final Time Seconds = BaseUnits.Time;
061
062  /** Alias for {@link #Seconds} to make combined unit definitions read more smoothly. */
063  public static final Time Second = Seconds; // singularized alias
064
065  /** 1/1000 of a {@link #Seconds Second}. */
066  public static final Time Milliseconds = Milli(Seconds);
067
068  /** Alias for {@link #Milliseconds} to make combined unit definitions read more smoothly. */
069  public static final Time Millisecond = Milliseconds; // singularized alias
070
071  /** 1/1,000,000 of a {@link #Seconds Second}. */
072  public static final Time Microseconds = Micro(Seconds);
073
074  /** Alias for {@link #Microseconds} to make combined unit definitions read more smoothly. */
075  public static final Time Microsecond = Microseconds; // singularized alias
076
077  /** 60 {@link #Seconds}. */
078  public static final Time Minutes =
079      derive(Seconds).aggregate(60).named("Minute").symbol("min").make();
080
081  /** Alias for {@link #Minutes} to make combined unit definitions read more smoothly. */
082  public static final Time Minute = Minutes; // singularized alias
083
084  // Angle
085  /**
086   * The base SI unit of angle, represented by the distance that the radius of a unit circle can
087   * wrap around its circumference.
088   */
089  public static final Angle Radians = BaseUnits.Angle;
090
091  /**
092   * The base SI unit of angle, represented by the distance that the radius of a unit circle can
093   * wrap around its circumference.
094   */
095  public static final Angle Radian = Radians; // alias
096
097  /**
098   * A single turn of an object around an external axis. Numerically equivalent to {@link
099   * #Rotations}, but may be semantically more expressive in certain scenarios.
100   */
101  public static final Angle Revolutions = new Angle(2 * Math.PI, "Revolution", "R");
102
103  /**
104   * A single turn of an object around an external axis. Numerically equivalent to a {@link
105   * #Rotation}, but may be semantically more expressive in certain scenarios.
106   */
107  public static final Angle Revolution = Revolutions; // alias
108
109  /**
110   * A single turn of an object around an internal axis. Numerically equivalent to {@link
111   * #Revolutions}, but may be semantically more expressive in certain scenarios.
112   */
113  public static final Angle Rotations = new Angle(2 * Math.PI, "Rotation", "R"); // alias revolution
114
115  /**
116   * A single turn of an object around an internal axis. Numerically equivalent to a {@link
117   * #Revolution}, but may be semantically more expressive in certain scenarios.
118   */
119  public static final Angle Rotation = Rotations; // alias
120
121  /** 1/360 of a turn around a circle, or 1/57.3 {@link #Radians}. */
122  public static final Angle Degrees =
123      derive(Revolutions).splitInto(360).named("Degree").symbol("°").make();
124
125  /** 1/360 of a turn around a circle, or 1/57.3 {@link #Radians}. */
126  public static final Angle Degree = Degrees; // alias
127
128  // Velocity
129  /**
130   * The standard SI unit of linear velocity, equivalent to travelling at a rate of one {@link
131   * #Meters Meter} per {@link #Second}.
132   */
133  public static final Velocity<Distance> MetersPerSecond = Meters.per(Second);
134
135  /**
136   * A unit of linear velocity equivalent to travelling at a rate one {@link #Feet Foot} per {@link
137   * #Second}.
138   */
139  public static final Velocity<Distance> FeetPerSecond = Feet.per(Second);
140
141  /**
142   * A unit of linear velocity equivalent to travelling at a rate of one {@link #Inches Inch} per
143   * {@link #Second}.
144   */
145  public static final Velocity<Distance> InchesPerSecond = Inches.per(Second);
146
147  /**
148   * A unit of angular velocity equivalent to spinning at a rate of one {@link #Revolutions
149   * Revolution} per {@link #Second}.
150   */
151  public static final Velocity<Angle> RevolutionsPerSecond = Revolutions.per(Second);
152
153  /**
154   * A unit of angular velocity equivalent to spinning at a rate of one {@link #Rotations Rotation}
155   * per {@link #Second}.
156   */
157  public static final Velocity<Angle> RotationsPerSecond = Rotations.per(Second);
158
159  /**
160   * A unit of angular velocity equivalent to spinning at a rate of one {@link #Rotations Rotation}
161   * per {@link #Minute}. Motor spec sheets often list maximum speeds in terms of RPM.
162   */
163  public static final Velocity<Angle> RPM = Rotations.per(Minute);
164
165  /**
166   * The standard SI unit of angular velocity, equivalent to spinning at a rate of one {@link
167   * #Radians Radian} per {@link #Second}.
168   */
169  public static final Velocity<Angle> RadiansPerSecond = Radians.per(Second);
170
171  /**
172   * A unit of angular velocity equivalent to spinning at a rate of one {@link #Degrees Degree} per
173   * {@link #Second}.
174   */
175  public static final Velocity<Angle> DegreesPerSecond = Degrees.per(Second);
176
177  // Acceleration
178  /**
179   * The standard SI unit of linear acceleration, equivalent to accelerating at a rate of one {@link
180   * #Meters Meter} per {@link #Second} every second.
181   */
182  public static final Velocity<Velocity<Distance>> MetersPerSecondPerSecond =
183      MetersPerSecond.per(Second);
184
185  /**
186   * A unit of acceleration equivalent to the pull of gravity on an object at sea level on Earth.
187   */
188  public static final Velocity<Velocity<Distance>> Gs =
189      derive(MetersPerSecondPerSecond).aggregate(9.80665).named("G").symbol("G").make();
190
191  // Mass
192  /** The base SI unit of mass. */
193  public static final Mass Kilograms = BaseUnits.Mass;
194
195  /** The base SI unit of mass. */
196  public static final Mass Kilogram = Kilograms; // alias
197
198  /** 1/1000 of a {@link #Kilogram}. */
199  public static final Mass Grams = Milli(Kilograms, "Gram", "g");
200
201  /** 1/1000 of a {@link #Kilogram}. */
202  public static final Mass Gram = Grams; // alias
203
204  /**
205   * A unit of mass equivalent to approximately 453 {@link #Grams}. This is <i>not</i> equivalent to
206   * pounds-force, which is the amount of force required to accelerate an object with one pound of
207   * mass at a rate of one {@link #Gs G}.
208   */
209  public static final Mass Pounds =
210      derive(Grams).aggregate(453.592).named("Pound").symbol("lb.").make();
211
212  /**
213   * A unit of mass equivalent to approximately 453 {@link #Grams}. This is <i>not</i> equivalent to
214   * pounds-force, which is the amount of force required to accelerate an object with one pound of
215   * mass at a rate of one {@link #Gs G}.
216   */
217  public static final Mass Pound = Pounds; // alias
218
219  /** 1/16 of a {@link #Pound}. */
220  public static final Mass Ounces =
221      derive(Pounds).splitInto(16).named("Ounce").symbol("oz.").make();
222
223  /** 1/16 of a {@link #Pound}. */
224  public static final Mass Ounce = Ounces; // alias
225
226  // Unitless
227  /** A dimensionless unit that performs no scaling whatsoever. */
228  public static final Dimensionless Value = BaseUnits.Value;
229
230  /**
231   * A dimensionless unit equal to to 1/100th of a {@link #Value}. A measurement of {@code
232   * Percent.of(42)} would be equivalent to {@code Value.of(0.42)}.
233   */
234  public static final Dimensionless Percent =
235      derive(Value).splitInto(100).named("Percent").symbol("%").make();
236
237  // Voltage
238  /** The base unit of electric potential. */
239  public static final Voltage Volts = BaseUnits.Voltage;
240
241  /** The base unit of electric potential. */
242  public static final Voltage Volt = Volts; // alias
243
244  /**
245   * 1/1000 of a {@link #Volt}. Useful when dealing with low-voltage applications like LED drivers
246   * or low-power circuits.
247   */
248  public static final Voltage Millivolts = Milli(Volts);
249
250  /**
251   * 1/1000 of a {@link #Volt}. Useful when dealing with low-voltage applications like LED drivers
252   * or low-power circuits.
253   */
254  public static final Voltage Millivolt = Millivolts; // alias
255
256  // Current
257  /** The base unit of electrical current. */
258  public static final Current Amps = BaseUnits.Current;
259
260  /** The base unit of electrical current. */
261  public static final Current Amp = Amps; // alias
262
263  /**
264   * A unit equal to 1/1000 of an {@link #Amp}. Useful when dealing with low-current applications
265   * like LED drivers or low-power circuits.
266   */
267  public static final Current Milliamps = Milli(Amps);
268
269  /**
270   * A unit equal to 1/1000 of an {@link #Amp}. Useful when dealing with low-current applications
271   * like LED drivers or low-power circuits.
272   */
273  public static final Current Milliamp = Milliamps; // alias
274
275  // Energy
276  /** The base unit of energy. */
277  public static final Energy Joules = BaseUnits.Energy;
278
279  /** The base unit of energy. */
280  public static final Energy Joule = Joules; // alias
281
282  /**
283   * A unit equal to 1/1000 of a {@link #Joule}. Useful when dealing with lower-power applications.
284   */
285  public static final Energy Millijoules = Milli(Joules);
286
287  /**
288   * A unit equal to 1/1000 of a {@link #Joule}. Useful when dealing with lower-power applications.
289   */
290  public static final Energy Millijoule = Millijoules; // alias
291
292  /**
293   * A unit equal to 1,000 {@link #Joules}. Useful when dealing with higher-level robot energy
294   * usage.
295   */
296  public static final Energy Kilojoules = Kilo(Joules);
297
298  /**
299   * A unit equal to 1,000 {@link #Joules}. Useful when dealing with higher-level robot energy
300   * usage.
301   */
302  public static final Energy Kilojoule = Kilojoules; // alias
303
304  // Power
305  /** The base unit of power. Equivalent to one {@link #Joule} per {@link #Second}. */
306  public static final Power Watts = BaseUnits.Power;
307
308  /** The base unit of power. Equivalent to one {@link #Joule} per {@link #Second}. */
309  public static final Power Watt = Watts; // alias
310
311  /**
312   * A unit equal to 1/1000 of a {@link #Watt}. Useful when dealing with lower-power applications.
313   */
314  public static final Power Milliwatts = Milli(Watts);
315
316  /**
317   * A unit equal to 1/1000 of a {@link #Watt}. Useful when dealing with lower-power applications.
318   */
319  public static final Power Milliwatt = Milliwatts; // alias
320
321  /**
322   * A unit equal to 745.7 {@link #Watts}. May be useful when dealing with high-power gearboxes and
323   * motors.
324   */
325  public static final Power Horsepower =
326      derive(Watts).aggregate(745.7).named("Horsepower").symbol("HP").make();
327
328  // Temperature
329  /**
330   * The base unit of temperature, where a value of 0 corresponds with absolutely zero energy in the
331   * measured system. Not particularly useful for robots unless you're cooling motors with liquid
332   * helium.
333   */
334  public static final Temperature Kelvin = BaseUnits.Temperature;
335
336  /**
337   * The base SI unit of temperature, where a value of 0 roughly corresponds to the freezing point
338   * of water and a value of 100 corresponds to the boiling point. Electronics tend to exhibit
339   * degraded performance or damage above 90 degrees Celsius.
340   */
341  public static final Temperature Celsius =
342      derive(Kelvin).offset(+273.15).named("Celsius").symbol("°C").make();
343
344  /**
345   * The base imperial (American) unit of temperature, where a value of 32 roughly corresponds to
346   * the freezing point of water and a value of 212 corresponds to the boiling point.
347   */
348  public static final Temperature Fahrenheit =
349      derive(Celsius)
350          .mappingInputRange(0, 100)
351          .toOutputRange(32, 212)
352          .named("Fahrenheit")
353          .symbol("°F")
354          .make();
355
356  // Standard feedforward units for kV and kA.
357  // kS and kG are just volts, which is already defined earlier
358  /**
359   * A standard unit for measuring linear mechanisms' feedforward voltages based on a model of the
360   * system and a desired commanded linear velocity.
361   */
362  public static final Per<Voltage, Velocity<Distance>> VoltsPerMeterPerSecond =
363      Volts.per(MetersPerSecond);
364
365  /**
366   * A standard unit for measuring linear mechanisms' feedforward voltages based on a model of the
367   * system and a desired commanded linear acceleration.
368   */
369  public static final Per<Voltage, Velocity<Velocity<Distance>>> VoltsPerMeterPerSecondSquared =
370      Volts.per(MetersPerSecondPerSecond);
371
372  /**
373   * A standard unit for measuring angular mechanisms' feedforward voltages based on a model of the
374   * system and a desired commanded angular velocity.
375   */
376  public static final Per<Voltage, Velocity<Angle>> VoltsPerRadianPerSecond =
377      Volts.per(RadiansPerSecond);
378
379  /**
380   * A standard unit for measuring angular mechanisms' feedforward voltages based on a model of the
381   * system and a desired commanded angular acceleration.
382   */
383  public static final Per<Voltage, Velocity<Velocity<Angle>>> VoltsPerRadianPerSecondSquared =
384      Volts.per(RadiansPerSecond.per(Second));
385
386  /**
387   * Creates a unit equal to a thousandth of the base unit, eg Milliseconds = Milli(Units.Seconds).
388   *
389   * @param <U> the type of the unit
390   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
391   * @param name the name of the new derived unit
392   * @param symbol the symbol of the new derived unit
393   * @return the milli-unit
394   */
395  @SuppressWarnings({"PMD.MethodName", "checkstyle:methodname"})
396  public static <U extends Unit<U>> U Milli(Unit<U> baseUnit, String name, String symbol) {
397    return derive(baseUnit).splitInto(1000).named(name).symbol(symbol).make();
398  }
399
400  /**
401   * Creates a unit equal to a thousandth of the base unit, eg Milliseconds = Milli(Units.Seconds).
402   *
403   * @param <U> the type of the unit
404   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
405   * @return the milli-unit
406   */
407  @SuppressWarnings({"PMD.MethodName", "checkstyle:methodname"})
408  public static <U extends Unit<U>> U Milli(Unit<U> baseUnit) {
409    return Milli(
410        baseUnit, "Milli" + baseUnit.name().toLowerCase(Locale.ROOT), "m" + baseUnit.symbol());
411  }
412
413  /**
414   * Creates a unit equal to a millionth of the base unit, eg {@code Microseconds =
415   * Micro(Units.Seconds, "Microseconds", 'us")}.
416   *
417   * @param <U> the type of the unit
418   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
419   * @param name the name of the new derived unit
420   * @param symbol the symbol of the new derived unit
421   * @return the micro-unit
422   */
423  @SuppressWarnings({"PMD.MethodName", "checkstyle:methodname"})
424  public static <U extends Unit<U>> U Micro(Unit<U> baseUnit, String name, String symbol) {
425    return derive(baseUnit).splitInto(1_000_000).named(name).symbol(symbol).make();
426  }
427
428  /**
429   * Creates a unit equal to a millionth of the base unit, eg Microseconds = Micro(Units.Seconds).
430   *
431   * @param <U> the type of the unit
432   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
433   * @return the micro-unit
434   */
435  @SuppressWarnings({"PMD.MethodName", "checkstyle:methodname"})
436  public static <U extends Unit<U>> U Micro(Unit<U> baseUnit) {
437    return Micro(
438        baseUnit, "Micro" + baseUnit.name().toLowerCase(Locale.ROOT), "u" + baseUnit.symbol());
439  }
440
441  /**
442   * Creates a unit equal to a thousand of the base unit, eg Kilograms = Kilo(Units.Grams).
443   *
444   * @param <U> the type of the unit
445   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
446   * @param name the name of the new derived unit
447   * @param symbol the symbol of the new derived unit
448   * @return the kilo-unit
449   */
450  @SuppressWarnings({"PMD.MethodName", "checkstyle:methodname"})
451  public static <U extends Unit<U>> U Kilo(Unit<U> baseUnit, String name, String symbol) {
452    return derive(baseUnit).aggregate(1000).named(name).symbol(symbol).make();
453  }
454
455  /**
456   * Creates a unit equal to a thousand of the base unit, eg Kilograms = Kilo(Units.Grams).
457   *
458   * @param <U> the type of the unit
459   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
460   * @return the kilo-unit
461   */
462  @SuppressWarnings({"PMD.MethodName", "checkstyle:methodname"})
463  public static <U extends Unit<U>> U Kilo(Unit<U> baseUnit) {
464    return Kilo(
465        baseUnit, "Kilo" + baseUnit.name().toLowerCase(Locale.ROOT), "K" + baseUnit.symbol());
466  }
467
468  /**
469   * Creates a new unit builder object based on a given input unit. The builder can be used to
470   * fluently describe a new unit in terms of its relation to the base unit.
471   *
472   * @param unit the base unit from which to derive a new unit
473   * @param <U> the dimension of the unit to derive
474   * @return a builder object
475   */
476  @SuppressWarnings("unchecked")
477  public static <U extends Unit<U>> UnitBuilder<U> derive(Unit<U> unit) {
478    return new UnitBuilder<>((U) unit);
479  }
480
481  /**
482   * Returns an anonymous unit for use when a specific unit type is not known. Do not use this
483   * directly.
484   *
485   * @param <U> the dimension of the desired anonymous unit
486   * @return the anonymous unit
487   */
488  @SuppressWarnings("unchecked")
489  public static <U extends Unit<U>> U anonymous() {
490    return (U) AnonymousBaseUnit;
491  }
492}