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