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 edu.wpi.first.units.measure.Dimensionless; 008 009/** 010 * A measure holds the magnitude and unit of some dimension, such as distance, time, or speed. An 011 * immutable measure is <i>immutable</i> and <i>type safe</i>, making it easy to use in concurrent 012 * situations and gives compile-time safety. Two measures with the same <i>unit</i> and 013 * <i>magnitude</i> are effectively equivalent objects. 014 * 015 * @param magnitude the magnitude of the measure in terms of its unit 016 * @param baseUnitMagnitude the magnitude of the measure in terms of its base unit 017 * @param unit the unit of the measurement 018 * @param <U> the unit type of the measure 019 */ 020public record ImmutableMeasure<U extends Unit>(double magnitude, double baseUnitMagnitude, U unit) 021 implements Measure<U> { 022 /** 023 * Creates a new measure in the given unit with a magnitude equal to the given one in base units. 024 * 025 * @param <U> the type of the units of measure 026 * @param baseUnitMagnitude the magnitude of the measure, in terms of the base unit of measure 027 * @param unit the unit of measure 028 * @return a new measure 029 */ 030 public static <U extends Unit> ImmutableMeasure<U> ofBaseUnits(double baseUnitMagnitude, U unit) { 031 return new ImmutableMeasure<>(unit.fromBaseUnits(baseUnitMagnitude), baseUnitMagnitude, unit); 032 } 033 034 /** 035 * Creates a new measure in the given unit with a magnitude in terms of that unit. 036 * 037 * @param <U> the type of the units of measure 038 * @param relativeMagnitude the magnitude of the measure 039 * @param unit the unit of measure 040 * @return a new measure 041 */ 042 public static <U extends Unit> ImmutableMeasure<U> ofRelativeUnits( 043 double relativeMagnitude, U unit) { 044 return new ImmutableMeasure<>(relativeMagnitude, unit.toBaseUnits(relativeMagnitude), unit); 045 } 046 047 @Override 048 public Measure<U> unaryMinus() { 049 return ofBaseUnits(0 - baseUnitMagnitude, unit); 050 } 051 052 @Override 053 public Measure<U> plus(Measure<? extends U> other) { 054 return ofBaseUnits(baseUnitMagnitude + other.baseUnitMagnitude(), unit); 055 } 056 057 @Override 058 public Measure<U> minus(Measure<? extends U> other) { 059 return ofBaseUnits(baseUnitMagnitude - other.baseUnitMagnitude(), unit); 060 } 061 062 @Override 063 public Measure<U> times(double multiplier) { 064 return ofBaseUnits(baseUnitMagnitude * multiplier, unit); 065 } 066 067 @Override 068 public Measure<U> times(Dimensionless multiplier) { 069 return ofBaseUnits(baseUnitMagnitude * multiplier.baseUnitMagnitude(), unit); 070 } 071 072 @Override 073 public Measure<U> div(double divisor) { 074 return ofBaseUnits(baseUnitMagnitude / divisor, unit); 075 } 076 077 @Override 078 public Measure<U> div(Dimensionless divisor) { 079 return ofBaseUnits(baseUnitMagnitude / divisor.baseUnitMagnitude(), unit); 080 } 081}