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 RPM = Rotations.per(Minute);
170
171  /**
172   * The standard SI unit of angular velocity, equivalent to spinning at a rate of one {@link
173   * #Radians Radian} per {@link #Second}.
174   */
175  public static final AngularVelocityUnit RadiansPerSecond = Radians.per(Second);
176
177  /**
178   * A unit of angular velocity equivalent to spinning at a rate of one {@link #Degrees Degree} per
179   * {@link #Second}.
180   */
181  public static final AngularVelocityUnit DegreesPerSecond = Degrees.per(Second);
182
183  /**
184   * The standard SI unit of frequency, equivalent to a periodic signal repeating once every {@link
185   * #Second}.
186   */
187  public static final FrequencyUnit Hertz =
188      derive(Value.per(Second)).named("Hertz").symbol("hz").make();
189
190  /** 1/1000th of a {@link #Hertz}. */
191  public static final FrequencyUnit Millihertz = Milli(Hertz);
192
193  // Acceleration
194  /**
195   * The standard SI unit of linear acceleration, equivalent to accelerating at a rate of one {@link
196   * #Meters Meter} per {@link #Second} every second.
197   */
198  public static final LinearAccelerationUnit MetersPerSecondPerSecond = MetersPerSecond.per(Second);
199
200  /**
201   * A unit of linear acceleration equivalent to accelerating at a rate of one {@link #Foot Foot}
202   * per {@link #Second} every second.
203   */
204  public static final LinearAccelerationUnit FeetPerSecondPerSecond = FeetPerSecond.per(Second);
205
206  /**
207   * A unit of angular acceleration equivalent to accelerating at a rate of one {@link #Rotations
208   * Rotation} per {@link #Second} every second.
209   */
210  public static final AngularAccelerationUnit RotationsPerSecondPerSecond =
211      RotationsPerSecond.per(Second);
212
213  /**
214   * The standard SI unit of angular acceleration, equivalent to accelerating at a rate of one
215   * {@link #Radians Radian} per {@link #Second} every second.
216   */
217  public static final AngularAccelerationUnit RadiansPerSecondPerSecond =
218      RadiansPerSecond.per(Second);
219
220  /**
221   * A unit of angular acceleration equivalent to accelerating at a rate of one {@link #Degrees
222   * Degree} per {@link #Second} every second.
223   */
224  public static final AngularAccelerationUnit DegreesPerSecondPerSecond =
225      DegreesPerSecond.per(Second);
226
227  /**
228   * A unit of acceleration equivalent to the pull of gravity on an object at sea level on Earth.
229   */
230  public static final LinearAccelerationUnit Gs =
231      derive(MetersPerSecondPerSecond).aggregate(9.80665).named("G").symbol("G").make();
232
233  // MassUnit
234  /** The standard SI unit of mass. */
235  public static final MassUnit Kilograms = BaseUnits.MassUnit;
236
237  /** The standard SI unit of mass. */
238  public static final MassUnit Kilogram = Kilograms; // alias
239
240  /** 1/1000 of a {@link #Kilogram}. */
241  public static final MassUnit Grams = Milli(Kilograms, "Gram", "g");
242
243  /** 1/1000 of a {@link #Kilogram}. */
244  public static final MassUnit Gram = Grams; // alias
245
246  /**
247   * A unit of mass equivalent to approximately 453 {@link #Grams}. This is <i>not</i> equivalent to
248   * pounds-force, which is the amount of force required to accelerate an object with one pound of
249   * mass at a rate of one {@link #Gs G}.
250   *
251   * @see #PoundsForce
252   */
253  public static final MassUnit Pounds =
254      derive(Grams).aggregate(453.592).named("Pound").symbol("lb.").make();
255
256  /**
257   * A unit of mass equivalent to approximately 453 {@link #Grams}. This is <i>not</i> equivalent to
258   * pounds-force, which is the amount of force required to accelerate an object with one pound of
259   * mass at a rate of one {@link #Gs G}.
260   *
261   * @see #PoundForce
262   */
263  public static final MassUnit Pound = Pounds; // alias
264
265  /** 1/16 of a {@link #Pound}. */
266  public static final MassUnit Ounces =
267      derive(Pounds).splitInto(16).named("Ounce").symbol("oz.").make();
268
269  /** 1/16 of a {@link #Pound}. */
270  public static final MassUnit Ounce = Ounces; // alias
271
272  // Force
273
274  /**
275   * The standard unit of force, equivalent to accelerating a mass of one {@link #Kilogram} at a
276   * rate of one {@link #MetersPerSecondPerSecond meter per second per second}.
277   */
278  public static final ForceUnit Newtons =
279      derive(Kilograms.mult(MetersPerSecondPerSecond)).named("Newton").symbol("N").make();
280
281  /**
282   * The standard unit of force, equivalent to the standard force of gravity applied to a one {@link
283   * #Kilogram} mass.
284   */
285  public static final ForceUnit Newton = Newtons;
286
287  /**
288   * The standard Imperial unit of force, equivalent to the standard force of gravity applied to a
289   * one {@link #Pound} mass.
290   */
291  public static final ForceUnit PoundsForce =
292      derive(Pounds.mult(Gs)).named("Pound-force").symbol("lbsf.").make();
293
294  /**
295   * The standard Imperial unit of force, equivalent to the standard force of gravity applied to a
296   * one {@link #Pound} mass.
297   */
298  public static final ForceUnit PoundForce = PoundsForce;
299
300  /**
301   * 1/16th of {@link #PoundsForce}, equivalent to the standard force of gravity applied to a one
302   * {@link #Ounce} mass.
303   */
304  public static final ForceUnit OuncesForce =
305      derive(Ounces.mult(Gs)).named("Ounce-force").symbol("ozf").make();
306
307  /**
308   * 1/16th of {@link #PoundsForce}, equivalent to the standard force of gravity applied to a one
309   * {@link #Ounce} mass.
310   */
311  public static final ForceUnit OunceForce = OuncesForce;
312
313  // Torque
314
315  /** The standard SI unit for torque. */
316  public static final TorqueUnit NewtonMeters = Meters.multAsTorque(Newtons);
317
318  /** The standard SI unit for torque. */
319  public static final TorqueUnit NewtonMeter = NewtonMeters;
320
321  /**
322   * The equivalent of one {@link #PoundsForce pound of force} applied to an object one {@link
323   * #Foot} away from its center of rotation.
324   */
325  public static final TorqueUnit PoundFeet = Feet.multAsTorque(PoundsForce);
326
327  /**
328   * The equivalent of one {@link #PoundsForce pound of force} applied to an object one {@link
329   * #Foot} away from its center of rotation.
330   */
331  public static final TorqueUnit PoundFoot = PoundFeet;
332
333  /**
334   * The equivalent of one {@link #PoundsForce pound of force} applied to an object one {@link
335   * #Inch} away from its center of rotation.
336   */
337  public static final TorqueUnit PoundInches = Inches.multAsTorque(PoundsForce);
338
339  /**
340   * The equivalent of one {@link #PoundsForce pound of force} applied to an object one {@link
341   * #Inch} away from its center of rotation.
342   */
343  public static final TorqueUnit PoundInch = PoundInches;
344
345  /**
346   * The equivalent of one {@link #OunceForce ounce of force} applied to an object one {@link #Inch}
347   * away from its center of rotation.
348   */
349  public static final TorqueUnit OunceInches = Inches.multAsTorque(OuncesForce);
350
351  /**
352   * The equivalent of one {@link #OunceForce ounce of force} applied to an object one {@link #Inch}
353   * away from its center of rotation.
354   */
355  public static final TorqueUnit OunceInch = OunceInches;
356
357  // Linear momentum
358
359  /**
360   * The standard SI unit for linear momentum, equivalent to a one {@link #Kilogram} mass moving at
361   * one {@link #MetersPerSecond}.
362   */
363  public static final LinearMomentumUnit KilogramMetersPerSecond = Kilograms.mult(MetersPerSecond);
364
365  // Angular momentum
366
367  /** The standard SI unit for angular momentum. */
368  public static final AngularMomentumUnit KilogramMetersSquaredPerSecond =
369      KilogramMetersPerSecond.mult(Meters);
370
371  // Moment of Inertia
372
373  /** The standard SI unit for moment of inertia. */
374  public static final MomentOfInertiaUnit KilogramSquareMeters =
375      KilogramMetersSquaredPerSecond.mult(RadiansPerSecond);
376
377  // VoltageUnit
378  /** The base unit of electric potential. */
379  public static final VoltageUnit Volts = BaseUnits.VoltageUnit;
380
381  /** The base unit of electric potential. */
382  public static final VoltageUnit Volt = Volts; // alias
383
384  /**
385   * 1/1000 of a {@link #Volt}. Useful when dealing with low-voltage applications like LED drivers
386   * or low-power circuits.
387   */
388  public static final VoltageUnit Millivolts = Milli(Volts);
389
390  /**
391   * 1/1000 of a {@link #Volt}. Useful when dealing with low-voltage applications like LED drivers
392   * or low-power circuits.
393   */
394  public static final VoltageUnit Millivolt = Millivolts; // alias
395
396  // CurrentUnit
397  /** The base unit of electrical current. */
398  public static final CurrentUnit Amps = BaseUnits.CurrentUnit;
399
400  /** The base unit of electrical current. */
401  public static final CurrentUnit Amp = Amps; // alias
402
403  /**
404   * A unit equal to 1/1000 of an {@link #Amp}. Useful when dealing with low-current applications
405   * like LED drivers or low-power circuits.
406   */
407  public static final CurrentUnit Milliamps = Milli(Amps);
408
409  /**
410   * A unit equal to 1/1000 of an {@link #Amp}. Useful when dealing with low-current applications
411   * like LED drivers or low-power circuits.
412   */
413  public static final CurrentUnit Milliamp = Milliamps; // alias
414
415  // ResistanceUnit
416  /** The base unit of resistance. Equivalent to one {@link #Volt} per {@link #Amp}. */
417  public static final ResistanceUnit Ohms = derive(Volts.per(Amp)).named("Ohm").symbol("Ω").make();
418
419  /** The base unit of resistance. Equivalent to one {@link #Volt} per {@link #Amp}. */
420  public static final ResistanceUnit Ohm = Ohms; // alias
421
422  /** A unit equal to 1,000 {@link #Ohms}. */
423  public static final ResistanceUnit KiloOhms = Kilo(Ohms);
424
425  /** A unit equal to 1,000 {@link #Ohms}. */
426  public static final ResistanceUnit KiloOhm = KiloOhms; // alias
427
428  /** A unit equal to 1/1000 of a {@link #Ohm}. */
429  public static final ResistanceUnit MilliOhms = Milli(Ohms);
430
431  /** A unit equal to 1/1000 of a {@link #Ohm}. */
432  public static final ResistanceUnit MilliOhm = MilliOhms; // alias
433
434  // EnergyUnit
435  /** The base unit of energy. */
436  public static final EnergyUnit Joules = BaseUnits.EnergyUnit;
437
438  /** The base unit of energy. */
439  public static final EnergyUnit Joule = Joules; // alias
440
441  /**
442   * A unit equal to 1/1000 of a {@link #Joule}. Useful when dealing with lower-power applications.
443   */
444  public static final EnergyUnit Millijoules = Milli(Joules);
445
446  /**
447   * A unit equal to 1/1000 of a {@link #Joule}. Useful when dealing with lower-power applications.
448   */
449  public static final EnergyUnit Millijoule = Millijoules; // alias
450
451  /**
452   * A unit equal to 1,000 {@link #Joules}. Useful when dealing with higher-level robot energy
453   * usage.
454   */
455  public static final EnergyUnit Kilojoules = Kilo(Joules);
456
457  /**
458   * A unit equal to 1,000 {@link #Joules}. Useful when dealing with higher-level robot energy
459   * usage.
460   */
461  public static final EnergyUnit Kilojoule = Kilojoules; // alias
462
463  // PowerUnit
464  /** The base unit of power. Equivalent to one {@link #Joule} per {@link #Second}. */
465  public static final PowerUnit Watts = derive(Joules.per(Second)).named("Watt").symbol("W").make();
466
467  /** The base unit of power. Equivalent to one {@link #Joule} per {@link #Second}. */
468  public static final PowerUnit Watt = Watts; // alias
469
470  /**
471   * A unit equal to 1/1000 of a {@link #Watt}. Useful when dealing with lower-power applications.
472   */
473  public static final PowerUnit Milliwatts = Milli(Watts);
474
475  /**
476   * A unit equal to 1/1000 of a {@link #Watt}. Useful when dealing with lower-power applications.
477   */
478  public static final PowerUnit Milliwatt = Milliwatts; // alias
479
480  /**
481   * A unit equal to 745.7 {@link #Watts}. May be useful when dealing with high-power gearboxes and
482   * motors.
483   */
484  public static final PowerUnit Horsepower =
485      derive(Watts).aggregate(745.7).named("Horsepower").symbol("HP").make();
486
487  // TemperatureUnit
488  /**
489   * The base unit of temperature, where a value of 0 corresponds with absolutely zero energy in the
490   * measured system. Not particularly useful for robots unless you're cooling motors with liquid
491   * helium.
492   */
493  public static final TemperatureUnit Kelvin = BaseUnits.TemperatureUnit;
494
495  /**
496   * The standard SI unit of temperature, where a value of 0 roughly corresponds to the freezing
497   * point of water and a value of 100 corresponds to the boiling point. Electronics tend to exhibit
498   * degraded performance or damage above 90 degrees Celsius.
499   */
500  public static final TemperatureUnit Celsius =
501      derive(Kelvin).offset(+273.15).named("Celsius").symbol("°C").make();
502
503  /**
504   * The base imperial (American) unit of temperature, where a value of 32 roughly corresponds to
505   * the freezing point of water and a value of 212 corresponds to the boiling point.
506   */
507  public static final TemperatureUnit Fahrenheit =
508      derive(Celsius)
509          .mappingInputRange(0, 100)
510          .toOutputRange(32, 212)
511          .named("Fahrenheit")
512          .symbol("°F")
513          .make();
514
515  // Standard feedforward units for kV and kA.
516  // kS and kG are just volts, which is already defined earlier
517  /**
518   * A standard unit for measuring linear mechanisms' feedforward voltages based on a model of the
519   * system and a desired commanded linear velocity.
520   */
521  public static final PerUnit<VoltageUnit, LinearVelocityUnit> VoltsPerMeterPerSecond =
522      Volts.per(MetersPerSecond);
523
524  /**
525   * A standard unit for measuring linear mechanisms' feedforward voltages based on a model of the
526   * system and a desired commanded linear acceleration.
527   */
528  public static final PerUnit<VoltageUnit, LinearAccelerationUnit> VoltsPerMeterPerSecondSquared =
529      Volts.per(MetersPerSecondPerSecond);
530
531  /**
532   * A standard unit for measuring angular mechanisms' feedforward voltages based on a model of the
533   * system and a desired commanded angular velocity.
534   */
535  public static final PerUnit<VoltageUnit, AngularVelocityUnit> VoltsPerRadianPerSecond =
536      Volts.per(RadiansPerSecond);
537
538  /**
539   * A standard unit for measuring angular mechanisms' feedforward voltages based on a model of the
540   * system and a desired commanded angular acceleration.
541   */
542  public static final PerUnit<VoltageUnit, AngularAccelerationUnit> VoltsPerRadianPerSecondSquared =
543      Volts.per(RadiansPerSecond.per(Second));
544
545  /**
546   * Creates a unit equal to a thousandth of the base unit, eg Milliseconds = Milli(Units.Seconds).
547   *
548   * @param <U> the type of the unit
549   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
550   * @param name the name of the new derived unit
551   * @param symbol the symbol of the new derived unit
552   * @return the milli-unit
553   */
554  @SuppressWarnings("checkstyle:methodname")
555  public static <U extends Unit> U Milli(U baseUnit, String name, String symbol) {
556    return derive(baseUnit).splitInto(1000).named(name).symbol(symbol).make();
557  }
558
559  /**
560   * Creates a unit equal to a thousandth of the base unit, eg Milliseconds = Milli(Units.Seconds).
561   *
562   * @param <U> the type of the unit
563   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
564   * @return the milli-unit
565   */
566  @SuppressWarnings("checkstyle:methodname")
567  public static <U extends Unit> U Milli(U baseUnit) {
568    return Milli(
569        baseUnit, "Milli" + baseUnit.name().toLowerCase(Locale.ROOT), "m" + baseUnit.symbol());
570  }
571
572  /**
573   * Creates a unit equal to a millionth of the base unit, eg {@code Microseconds =
574   * Micro(Units.Seconds, "Microseconds", 'us")}.
575   *
576   * @param <U> the type of the unit
577   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
578   * @param name the name of the new derived unit
579   * @param symbol the symbol of the new derived unit
580   * @return the micro-unit
581   */
582  @SuppressWarnings("checkstyle:methodname")
583  public static <U extends Unit> U Micro(U baseUnit, String name, String symbol) {
584    return derive(baseUnit).splitInto(1_000_000).named(name).symbol(symbol).make();
585  }
586
587  /**
588   * Creates a unit equal to a millionth of the base unit, eg Microseconds = Micro(Units.Seconds).
589   *
590   * @param <U> the type of the unit
591   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
592   * @return the micro-unit
593   */
594  @SuppressWarnings("checkstyle:methodname")
595  public static <U extends Unit> U Micro(U baseUnit) {
596    return Micro(
597        baseUnit, "Micro" + baseUnit.name().toLowerCase(Locale.ROOT), "u" + baseUnit.symbol());
598  }
599
600  /**
601   * Creates a unit equal to a thousand of the base unit, eg Kilograms = Kilo(Units.Grams).
602   *
603   * @param <U> the type of the unit
604   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
605   * @param name the name of the new derived unit
606   * @param symbol the symbol of the new derived unit
607   * @return the kilo-unit
608   */
609  @SuppressWarnings("checkstyle:methodname")
610  public static <U extends Unit> U Kilo(U baseUnit, String name, String symbol) {
611    return derive(baseUnit).aggregate(1000).named(name).symbol(symbol).make();
612  }
613
614  /**
615   * Creates a unit equal to a thousand of the base unit, eg Kilograms = Kilo(Units.Grams).
616   *
617   * @param <U> the type of the unit
618   * @param baseUnit the unit being derived from. This does not have to be the base unit of measure
619   * @return the kilo-unit
620   */
621  @SuppressWarnings("checkstyle:methodname")
622  public static <U extends Unit> U Kilo(U baseUnit) {
623    return Kilo(
624        baseUnit, "Kilo" + baseUnit.name().toLowerCase(Locale.ROOT), "K" + baseUnit.symbol());
625  }
626
627  /**
628   * Creates a new unit builder object based on a given input unit. The builder can be used to
629   * fluently describe a new unit in terms of its relation to the base unit.
630   *
631   * @param unit the base unit from which to derive a new unit
632   * @param <U> the dimension of the unit to derive
633   * @return a builder object
634   */
635  public static <U extends Unit> UnitBuilder<U> derive(U unit) {
636    return new UnitBuilder<>(unit);
637  }
638}