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  // Unitless
018  /** A dimensionless unit that performs no scaling whatsoever. */
019  public static final DimensionlessUnit Value = BaseUnits.Value;
020
021  /**
022   * A dimensionless unit equal to to 1/100th of a {@link #Value}. A measurement of {@code
023   * Percent.of(42)} would be equivalent to {@code Value.of(0.42)}.
024   */
025  public static final DimensionlessUnit Percent =
026      derive(Value).splitInto(100).named("Percent").symbol("%").make();
027
028  // DistanceUnit
029  /** The base unit of distance. */
030  public static final DistanceUnit Meters = BaseUnits.DistanceUnit;
031
032  /** The base unit of distance. */
033  public static final DistanceUnit Meter = Meters; // alias
034
035  /** 1/1000 of a {@link #Meter}. */
036  public static final DistanceUnit Millimeters = Milli(Meters, "Millimeter", "mm");
037
038  /** 1/1000 of a {@link #Meter}. */
039  public static final DistanceUnit Millimeter = Millimeters; // alias
040
041  /** 1/100 of a {@link #Meter}. */
042  public static final DistanceUnit Centimeters =
043      derive(Meters).splitInto(100).named("Centimeter").symbol("cm").make();
044
045  /** 1/100 of a {@link #Meter}. */
046  public static final DistanceUnit Centimeter = Centimeters; // alias
047
048  /** 25.4/1000 of a {@link #Meter} and 1/12 of a {@link #Foot}. */
049  public static final DistanceUnit Inches =
050      derive(Millimeters).aggregate(25.4).named("Inch").symbol("in").make();
051
052  /** 25.4/1000 of a {@link #Meter} and 1/12 of a {@link #Foot}. */
053  public static final DistanceUnit Inch = Inches; // alias
054
055  /** 304.8/1000 of a {@link #Meter}, or 12 {@link #Inches}. */
056  public static final DistanceUnit Feet =
057      derive(Inches).aggregate(12).named("Foot").symbol("ft").make();
058
059  /** 304.8/1000 of a {@link #Meter}, or 12 {@link #Inches}. */
060  public static final DistanceUnit Foot = Feet; // alias
061
062  // TimeUnit
063  /** The base unit of time. */
064  public static final TimeUnit Seconds = BaseUnits.TimeUnit;
065
066  /** Alias for {@link #Seconds} to make combined unit definitions read more smoothly. */
067  public static final TimeUnit Second = Seconds; // singularized alias
068
069  /** 1/1000 of a {@link #Seconds Second}. */
070  public static final TimeUnit Milliseconds = Milli(Seconds);
071
072  /** Alias for {@link #Milliseconds} to make combined unit definitions read more smoothly. */
073  public static final TimeUnit Millisecond = Milliseconds; // singularized alias
074
075  /** 1/1,000,000 of a {@link #Seconds Second}. */
076  public static final TimeUnit Microseconds = Micro(Seconds);
077
078  /** Alias for {@link #Microseconds} to make combined unit definitions read more smoothly. */
079  public static final TimeUnit Microsecond = Microseconds; // singularized alias
080
081  /** 60 {@link #Seconds}. */
082  public static final TimeUnit Minutes =
083      derive(Seconds).aggregate(60).named("Minute").symbol("min").make();
084
085  /** Alias for {@link #Minutes} to make combined unit definitions read more smoothly. */
086  public static final TimeUnit Minute = Minutes; // singularized alias
087
088  // AngleUnit
089  /**
090   * The standard SI unit of angle, represented by the distance that the radius of a unit circle can
091   * wrap around its circumference.
092   */
093  public static final AngleUnit Radians = BaseUnits.AngleUnit;
094
095  /**
096   * The standard SI unit of angle, represented by the distance that the radius of a unit circle can
097   * wrap around its circumference.
098   */
099  public static final AngleUnit Radian = Radians; // alias
100
101  /**
102   * A single turn of an object around an external axis. Numerically equivalent to {@link
103   * #Rotations}, but may be semantically more expressive in certain scenarios.
104   */
105  public static final AngleUnit Revolutions =
106      derive(Radians).aggregate(2 * Math.PI).named("Revolution").symbol("R").make();
107
108  /**
109   * A single turn of an object around an external axis. Numerically equivalent to a {@link
110   * #Rotation}, but may be semantically more expressive in certain scenarios.
111   */
112  public static final AngleUnit Revolution = Revolutions; // alias
113
114  /**
115   * A single turn of an object around an internal axis. Numerically equivalent to {@link
116   * #Revolutions}, but may be semantically more expressive in certain scenarios.
117   */
118  public static final AngleUnit Rotations =
119      derive(Revolutions).named("Rotation").symbol("R").make();
120
121  /**
122   * A single turn of an object around an internal axis. Numerically equivalent to a {@link
123   * #Revolution}, but may be semantically more expressive in certain scenarios.
124   */
125  public static final AngleUnit Rotation = Rotations; // alias
126
127  /** 1/360 of a turn around a circle, or 1/57.3 {@link #Radians}. */
128  public static final AngleUnit Degrees =
129      derive(Revolutions).splitInto(360).named("Degree").symbol("°").make();
130
131  /** 1/360 of a turn around a circle, or 1/57.3 {@link #Radians}. */
132  public static final AngleUnit Degree = Degrees; // alias
133
134  // VelocityUnit
135  /**
136   * The standard SI unit of linear velocity, equivalent to travelling at a rate of one {@link
137   * #Meters Meter} per {@link #Second}.
138   */
139  public static final LinearVelocityUnit MetersPerSecond = Meters.per(Second);
140
141  /**
142   * A unit of linear velocity equivalent to travelling at a rate one {@link #Feet Foot} per {@link
143   * #Second}.
144   */
145  public static final LinearVelocityUnit FeetPerSecond = Feet.per(Second);
146
147  /**
148   * A unit of linear velocity equivalent to travelling at a rate of one {@link #Inches Inch} per
149   * {@link #Second}.
150   */
151  public static final LinearVelocityUnit InchesPerSecond = Inches.per(Second);
152
153  /**
154   * A unit of angular velocity equivalent to spinning at a rate of one {@link #Revolutions
155   * Revolution} per {@link #Second}.
156   */
157  public static final AngularVelocityUnit RevolutionsPerSecond = Revolutions.per(Second);
158
159  /**
160   * A unit of angular velocity equivalent to spinning at a rate of one {@link #Rotations Rotation}
161   * per {@link #Second}.
162   */
163  public static final AngularVelocityUnit RotationsPerSecond = Rotations.per(Second);
164
165  /**
166   * A unit of angular velocity equivalent to spinning at a rate of one {@link #Rotations Rotation}
167   * per {@link #Minute}. Motor spec sheets often list maximum speeds in terms of RPM.
168   */
169  public static final AngularVelocityUnit RotationsPerMinute = Rotations.per(Minute);
170
171  /**
172   * A unit of angular velocity equivalent to spinning at a rate of one {@link #Rotations Rotation}
173   * per {@link #Minute}. Motor spec sheets often list maximum speeds in terms of RPM.
174   */
175  public static final AngularVelocityUnit RPM = RotationsPerMinute; // alias
176
177  /**
178   * The standard SI unit of angular velocity, equivalent to spinning at a rate of one {@link
179   * #Radians Radian} per {@link #Second}.
180   */
181  public static final AngularVelocityUnit RadiansPerSecond = Radians.per(Second);
182
183  /**
184   * A unit of angular velocity equivalent to spinning at a rate of one {@link #Degrees Degree} per
185   * {@link #Second}.
186   */
187  public static final AngularVelocityUnit DegreesPerSecond = Degrees.per(Second);
188
189  /**
190   * The standard SI unit of frequency, equivalent to a periodic signal repeating once every {@link
191   * #Second}.
192   */
193  public static final FrequencyUnit Hertz =
194      derive(Value.per(Second)).named("Hertz").symbol("hz").make();
195
196  /** 1/1000th of a {@link #Hertz}. */
197  public static final FrequencyUnit Millihertz = Milli(Hertz);
198
199  // Acceleration
200  /**
201   * The standard SI unit of linear acceleration, equivalent to accelerating at a rate of one {@link
202   * #Meters Meter} per {@link #Second} every second.
203   */
204  public static final LinearAccelerationUnit MetersPerSecondPerSecond = MetersPerSecond.per(Second);
205
206  /**
207   * A unit of linear acceleration equivalent to accelerating at a rate of one {@link #Foot Foot}
208   * per {@link #Second} every second.
209   */
210  public static final LinearAccelerationUnit FeetPerSecondPerSecond = FeetPerSecond.per(Second);
211
212  /**
213   * A unit of linear acceleration equivalent to accelerating at a rate of one {@link #Inch Inch}
214   * per {@link #Second} every second.
215   */
216  public static final LinearAccelerationUnit InchesPerSecondPerSecond = InchesPerSecond.per(Second);
217
218  /**
219   * A unit of angular acceleration equivalent to accelerating at a rate of one {@link #Rotations
220   * Rotation} per {@link #Second} every second.
221   */
222  public static final AngularAccelerationUnit RotationsPerSecondPerSecond =
223      RotationsPerSecond.per(Second);
224
225  /**
226   * The standard SI unit of angular acceleration, equivalent to accelerating at a rate of one
227   * {@link #Radians Radian} per {@link #Second} every second.
228   */
229  public static final AngularAccelerationUnit RadiansPerSecondPerSecond =
230      RadiansPerSecond.per(Second);
231
232  /**
233   * A unit of angular acceleration equivalent to accelerating at a rate of one {@link #Degrees
234   * Degree} per {@link #Second} every second.
235   */
236  public static final AngularAccelerationUnit DegreesPerSecondPerSecond =
237      DegreesPerSecond.per(Second);
238
239  /**
240   * A unit of acceleration equivalent to the pull of gravity on an object at sea level on Earth.
241   */
242  public static final LinearAccelerationUnit Gs =
243      derive(MetersPerSecondPerSecond).aggregate(9.80665).named("G").symbol("G").make();
244
245  // MassUnit
246  /** The standard SI unit of mass. */
247  public static final MassUnit Kilograms = BaseUnits.MassUnit;
248
249  /** The standard SI unit of mass. */
250  public static final MassUnit Kilogram = Kilograms; // alias
251
252  /** 1/1000 of a {@link #Kilogram}. */
253  public static final MassUnit Grams = Milli(Kilograms, "Gram", "g");
254
255  /** 1/1000 of a {@link #Kilogram}. */
256  public static final MassUnit Gram = Grams; // alias
257
258  /**
259   * A unit of mass equivalent to approximately 453 {@link #Grams}. This is <i>not</i> equivalent to
260   * pounds-force, which is the amount of force required to accelerate an object with one pound of
261   * mass at a rate of one {@link #Gs G}.
262   *
263   * @see #PoundsForce
264   */
265  public static final MassUnit Pounds =
266      derive(Grams).aggregate(453.592).named("Pound").symbol("lb.").make();
267
268  /**
269   * A unit of mass equivalent to approximately 453 {@link #Grams}. This is <i>not</i> equivalent to
270   * pounds-force, which is the amount of force required to accelerate an object with one pound of
271   * mass at a rate of one {@link #Gs G}.
272   *
273   * @see #PoundForce
274   */
275  public static final MassUnit Pound = Pounds; // alias
276
277  /** 1/16 of a {@link #Pound}. */
278  public static final MassUnit Ounces =
279      derive(Pounds).splitInto(16).named("Ounce").symbol("oz.").make();
280
281  /** 1/16 of a {@link #Pound}. */
282  public static final MassUnit Ounce = Ounces; // alias
283
284  // Force
285
286  /**
287   * The standard unit of force, equivalent to accelerating a mass of one {@link #Kilogram} at a
288   * rate of one {@link #MetersPerSecondPerSecond meter per second per second}.
289   */
290  public static final ForceUnit Newtons =
291      derive(Kilograms.mult(MetersPerSecondPerSecond)).named("Newton").symbol("N").make();
292
293  /**
294   * The standard unit of force, equivalent to the standard force of gravity applied to a one {@link
295   * #Kilogram} mass.
296   */
297  public static final ForceUnit Newton = Newtons;
298
299  /**
300   * The standard Imperial unit of force, equivalent to the standard force of gravity applied to a
301   * one {@link #Pound} mass.
302   */
303  public static final ForceUnit PoundsForce =
304      derive(Pounds.mult(Gs)).named("Pound-force").symbol("lbsf.").make();
305
306  /**
307   * The standard Imperial unit of force, equivalent to the standard force of gravity applied to a
308   * one {@link #Pound} mass.
309   */
310  public static final ForceUnit PoundForce = PoundsForce;
311
312  /**
313   * 1/16th of {@link #PoundsForce}, equivalent to the standard force of gravity applied to a one
314   * {@link #Ounce} mass.
315   */
316  public static final ForceUnit OuncesForce =
317      derive(Ounces.mult(Gs)).named("Ounce-force").symbol("ozf").make();
318
319  /**
320   * 1/16th of {@link #PoundsForce}, equivalent to the standard force of gravity applied to a one
321   * {@link #Ounce} mass.
322   */
323  public static final ForceUnit OunceForce = OuncesForce;
324
325  // Torque
326
327  /** The standard SI unit for torque. */
328  public static final TorqueUnit NewtonMeters = Meters.multAsTorque(Newtons);
329
330  /** The standard SI unit for torque. */
331  public static final TorqueUnit NewtonMeter = NewtonMeters;
332
333  /**
334   * The equivalent of one {@link #PoundsForce pound of force} applied to an object one {@link
335   * #Foot} away from its center of rotation.
336   */
337  public static final TorqueUnit PoundFeet = Feet.multAsTorque(PoundsForce);
338
339  /**
340   * The equivalent of one {@link #PoundsForce pound of force} applied to an object one {@link
341   * #Foot} away from its center of rotation.
342   */
343  public static final TorqueUnit PoundFoot = PoundFeet;
344
345  /**
346   * The equivalent of one {@link #PoundsForce pound of force} applied to an object one {@link
347   * #Inch} away from its center of rotation.
348   */
349  public static final TorqueUnit PoundInches = Inches.multAsTorque(PoundsForce);
350
351  /**
352   * The equivalent of one {@link #PoundsForce pound of force} applied to an object one {@link
353   * #Inch} away from its center of rotation.
354   */
355  public static final TorqueUnit PoundInch = PoundInches;
356
357  /**
358   * The equivalent of one {@link #OunceForce ounce of force} applied to an object one {@link #Inch}
359   * away from its center of rotation.
360   */
361  public static final TorqueUnit OunceInches = Inches.multAsTorque(OuncesForce);
362
363  /**
364   * The equivalent of one {@link #OunceForce ounce of force} applied to an object one {@link #Inch}
365   * away from its center of rotation.
366   */
367  public static final TorqueUnit OunceInch = OunceInches;
368
369  // Linear momentum
370
371  /**
372   * The standard SI unit for linear momentum, equivalent to a one {@link #Kilogram} mass moving at
373   * one {@link #MetersPerSecond}.
374   */
375  public static final LinearMomentumUnit KilogramMetersPerSecond = Kilograms.mult(MetersPerSecond);
376
377  // Angular momentum
378
379  /** The standard SI unit for angular momentum. */
380  public static final AngularMomentumUnit KilogramMetersSquaredPerSecond =
381      KilogramMetersPerSecond.mult(Meters);
382
383  // Moment of Inertia
384
385  /** The standard SI unit for moment of inertia. */
386  public static final MomentOfInertiaUnit KilogramSquareMeters =
387      KilogramMetersSquaredPerSecond.per(RadiansPerSecond);
388
389  // VoltageUnit
390  /** The base unit of electric potential. */
391  public static final VoltageUnit Volts = BaseUnits.VoltageUnit;
392
393  /** The base unit of electric potential. */
394  public static final VoltageUnit Volt = Volts; // alias
395
396  /**
397   * 1/1000 of a {@link #Volt}. Useful when dealing with low-voltage applications like LED drivers
398   * or low-power circuits.
399   */
400  public static final VoltageUnit Millivolts = Milli(Volts);
401
402  /**
403   * 1/1000 of a {@link #Volt}. Useful when dealing with low-voltage applications like LED drivers
404   * or low-power circuits.
405   */
406  public static final VoltageUnit Millivolt = Millivolts; // alias
407
408  // CurrentUnit
409  /** The base unit of electrical current. */
410  public static final CurrentUnit Amps = BaseUnits.CurrentUnit;
411
412  /** The base unit of electrical current. */
413  public static final CurrentUnit Amp = Amps; // alias
414
415  /**
416   * A unit equal to 1/1000 of an {@link #Amp}. Useful when dealing with low-current applications
417   * like LED drivers or low-power circuits.
418   */
419  public static final CurrentUnit Milliamps = Milli(Amps);
420
421  /**
422   * A unit equal to 1/1000 of an {@link #Amp}. Useful when dealing with low-current applications
423   * like LED drivers or low-power circuits.
424   */
425  public static final CurrentUnit Milliamp = Milliamps; // alias
426
427  // ResistanceUnit
428  /** The base unit of resistance. Equivalent to one {@link #Volt} per {@link #Amp}. */
429  public static final ResistanceUnit Ohms = derive(Volts.per(Amp)).named("Ohm").symbol("Ω").make();
430
431  /** The base unit of resistance. Equivalent to one {@link #Volt} per {@link #Amp}. */
432  public static final ResistanceUnit Ohm = Ohms; // alias
433
434  /** A unit equal to 1,000 {@link #Ohms}. */
435  public static final ResistanceUnit KiloOhms = Kilo(Ohms);
436
437  /** A unit equal to 1,000 {@link #Ohms}. */
438  public static final ResistanceUnit KiloOhm = KiloOhms; // alias
439
440  /** A unit equal to 1/1000 of a {@link #Ohm}. */
441  public static final ResistanceUnit MilliOhms = Milli(Ohms);
442
443  /** A unit equal to 1/1000 of a {@link #Ohm}. */
444  public static final ResistanceUnit MilliOhm = MilliOhms; // alias
445
446  // EnergyUnit
447  /** The base unit of energy. */
448  public static final EnergyUnit Joules = BaseUnits.EnergyUnit;
449
450  /** The base unit of energy. */
451  public static final EnergyUnit Joule = Joules; // alias
452
453  /**
454   * A unit equal to 1/1000 of a {@link #Joule}. Useful when dealing with lower-power applications.
455   */
456  public static final EnergyUnit Millijoules = Milli(Joules);
457
458  /**
459   * A unit equal to 1/1000 of a {@link #Joule}. Useful when dealing with lower-power applications.
460   */
461  public static final EnergyUnit Millijoule = Millijoules; // alias
462
463  /**
464   * A unit equal to 1,000 {@link #Joules}. Useful when dealing with higher-level robot energy
465   * usage.
466   */
467  public static final EnergyUnit Kilojoules = Kilo(Joules);
468
469  /**
470   * A unit equal to 1,000 {@link #Joules}. Useful when dealing with higher-level robot energy
471   * usage.
472   */
473  public static final EnergyUnit Kilojoule = Kilojoules; // alias
474
475  // PowerUnit
476  /** The base unit of power. Equivalent to one {@link #Joule} per {@link #Second}. */
477  public static final PowerUnit Watts = derive(Joules.per(Second)).named("Watt").symbol("W").make();
478
479  /** The base unit of power. Equivalent to one {@link #Joule} per {@link #Second}. */
480  public static final PowerUnit Watt = Watts; // alias
481
482  /**
483   * A unit equal to 1/1000 of a {@link #Watt}. Useful when dealing with lower-power applications.
484   */
485  public static final PowerUnit Milliwatts = Milli(Watts);
486
487  /**
488   * A unit equal to 1/1000 of a {@link #Watt}. Useful when dealing with lower-power applications.
489   */
490  public static final PowerUnit Milliwatt = Milliwatts; // alias
491
492  /**
493   * A unit equal to 745.7 {@link #Watts}. May be useful when dealing with high-power gearboxes and
494   * motors.
495   */
496  public static final PowerUnit Horsepower =
497      derive(Watts).aggregate(745.7).named("Horsepower").symbol("HP").make();
498
499  // TemperatureUnit
500  /**
501   * The base unit of temperature, where a value of 0 corresponds with absolutely zero energy in the
502   * measured system. Not particularly useful for robots unless you're cooling motors with liquid
503   * helium.
504   */
505  public static final TemperatureUnit Kelvin = BaseUnits.TemperatureUnit;
506
507  /**
508   * The standard SI unit of temperature, where a value of 0 roughly corresponds to the freezing
509   * point of water and a value of 100 corresponds to the boiling point. Electronics tend to exhibit
510   * degraded performance or damage above 90 degrees Celsius.
511   */
512  public static final TemperatureUnit Celsius =
513      derive(Kelvin).offset(+273.15).named("Celsius").symbol("°C").make();
514
515  /**
516   * The base imperial (American) unit of temperature, where a value of 32 roughly corresponds to
517   * the freezing point of water and a value of 212 corresponds to the boiling point.
518   */
519  public static final TemperatureUnit Fahrenheit =
520      derive(Celsius)
521          .mappingInputRange(0, 100)
522          .toOutputRange(32, 212)
523          .named("Fahrenheit")
524          .symbol("°F")
525          .make();
526
527  // Standard feedforward units for kV and kA.
528  // kS and kG are just volts, which is already defined earlier
529  /**
530   * A standard unit for measuring linear mechanisms' feedforward voltages based on a model of the
531   * system and a desired commanded linear velocity.
532   */
533  public static final PerUnit<VoltageUnit, LinearVelocityUnit> VoltsPerMeterPerSecond =
534      Volts.per(MetersPerSecond);
535
536  /**
537   * A standard unit for measuring linear mechanisms' feedforward voltages based on a model of the
538   * system and a desired commanded linear acceleration.
539   */
540  public static final PerUnit<VoltageUnit, LinearAccelerationUnit> VoltsPerMeterPerSecondSquared =
541      Volts.per(MetersPerSecondPerSecond);
542
543  /**
544   * A standard unit for measuring angular mechanisms' feedforward voltages based on a model of the
545   * system and a desired commanded angular velocity.
546   */
547  public static final PerUnit<VoltageUnit, AngularVelocityUnit> VoltsPerRadianPerSecond =
548      Volts.per(RadiansPerSecond);
549
550  /**
551   * A standard unit for measuring angular mechanisms' feedforward voltages based on a model of the
552   * system and a desired commanded angular acceleration.
553   */
554  public static final PerUnit<VoltageUnit, AngularAccelerationUnit> VoltsPerRadianPerSecondSquared =
555      Volts.per(RadiansPerSecond.per(Second));
556
557  /**
558   * Creates a unit equal to a thousandth of the base unit, eg Milliseconds = Milli(Units.Seconds).
559   *
560   * @param <U> the type of the unit
561   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
562   * @param name the name of the new derived unit
563   * @param symbol the symbol of the new derived unit
564   * @return the milli-unit
565   */
566  @SuppressWarnings("checkstyle:methodname")
567  public static <U extends Unit> U Milli(U baseUnit, String name, String symbol) {
568    return derive(baseUnit).splitInto(1000).named(name).symbol(symbol).make();
569  }
570
571  /**
572   * Creates a unit equal to a thousandth of the base unit, eg Milliseconds = Milli(Units.Seconds).
573   *
574   * @param <U> the type of the unit
575   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
576   * @return the milli-unit
577   */
578  @SuppressWarnings("checkstyle:methodname")
579  public static <U extends Unit> U Milli(U baseUnit) {
580    return Milli(
581        baseUnit, "Milli" + baseUnit.name().toLowerCase(Locale.ROOT), "m" + baseUnit.symbol());
582  }
583
584  /**
585   * Creates a unit equal to a millionth of the base unit, eg {@code Microseconds =
586   * Micro(Units.Seconds, "Microseconds", 'us")}.
587   *
588   * @param <U> the type of the unit
589   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
590   * @param name the name of the new derived unit
591   * @param symbol the symbol of the new derived unit
592   * @return the micro-unit
593   */
594  @SuppressWarnings("checkstyle:methodname")
595  public static <U extends Unit> U Micro(U baseUnit, String name, String symbol) {
596    return derive(baseUnit).splitInto(1_000_000).named(name).symbol(symbol).make();
597  }
598
599  /**
600   * Creates a unit equal to a millionth of the base unit, eg Microseconds = Micro(Units.Seconds).
601   *
602   * @param <U> the type of the unit
603   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
604   * @return the micro-unit
605   */
606  @SuppressWarnings("checkstyle:methodname")
607  public static <U extends Unit> U Micro(U baseUnit) {
608    return Micro(
609        baseUnit, "Micro" + baseUnit.name().toLowerCase(Locale.ROOT), "u" + baseUnit.symbol());
610  }
611
612  /**
613   * Creates a unit equal to a thousand of the base unit, eg Kilograms = Kilo(Units.Grams).
614   *
615   * @param <U> the type of the unit
616   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
617   * @param name the name of the new derived unit
618   * @param symbol the symbol of the new derived unit
619   * @return the kilo-unit
620   */
621  @SuppressWarnings("checkstyle:methodname")
622  public static <U extends Unit> U Kilo(U baseUnit, String name, String symbol) {
623    return derive(baseUnit).aggregate(1000).named(name).symbol(symbol).make();
624  }
625
626  /**
627   * Creates a unit equal to a thousand of the base unit, eg Kilograms = Kilo(Units.Grams).
628   *
629   * @param <U> the type of the unit
630   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
631   * @return the kilo-unit
632   */
633  @SuppressWarnings("checkstyle:methodname")
634  public static <U extends Unit> U Kilo(U baseUnit) {
635    return Kilo(
636        baseUnit, "Kilo" + baseUnit.name().toLowerCase(Locale.ROOT), "K" + baseUnit.symbol());
637  }
638
639  /**
640   * Creates a new unit builder object based on a given input unit. The builder can be used to
641   * fluently describe a new unit in terms of its relation to the base unit.
642   *
643   * @param unit the base unit from which to derive a new unit
644   * @param <U> the dimension of the unit to derive
645   * @return a builder object
646   */
647  public static <U extends Unit> UnitBuilder<U> derive(U unit) {
648    return new UnitBuilder<>(unit);
649  }
650}