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