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 static edu.wpi.first.units.Units.Value; 008 009import edu.wpi.first.units.measure.Frequency; 010import edu.wpi.first.units.measure.ImmutableFrequency; 011import edu.wpi.first.units.measure.MutFrequency; 012 013/** A unit of frequency like {@link edu.wpi.first.units.Units#Hertz}. */ 014public final class FrequencyUnit extends PerUnit<DimensionlessUnit, TimeUnit> { 015 private static final CombinatoryUnitCache<DimensionlessUnit, TimeUnit, FrequencyUnit> cache = 016 new CombinatoryUnitCache<>(FrequencyUnit::new); 017 018 FrequencyUnit(DimensionlessUnit numerator, TimeUnit denominator) { 019 super( 020 numerator.isBaseUnit() && denominator.isBaseUnit() 021 ? null 022 : combine(numerator.getBaseUnit(), denominator.getBaseUnit()), 023 numerator, 024 denominator); 025 } 026 027 FrequencyUnit( 028 FrequencyUnit baseUnit, 029 UnaryFunction toBaseConverter, 030 UnaryFunction fromBaseConverter, 031 String name, 032 String symbol) { 033 super(baseUnit, toBaseConverter, fromBaseConverter, name, symbol); 034 } 035 036 /** 037 * Combines a dimensionless unit and a cycle period to create a frequency. 038 * 039 * @param dim the dimensionless unit 040 * @param period the unit of time 041 * @return the combined unit of frequency 042 */ 043 public static FrequencyUnit combine(DimensionlessUnit dim, TimeUnit period) { 044 return cache.combine(dim, period); 045 } 046 047 @Override 048 public FrequencyUnit getBaseUnit() { 049 return (FrequencyUnit) super.getBaseUnit(); 050 } 051 052 /** 053 * Inverts a unit of time to get its corresponding frequency (as if the unit of time is the period 054 * of the frequency). 055 * 056 * @param time period of the associated frequency 057 * @return the frequency associated with the period 058 */ 059 public static FrequencyUnit inverse(TimeUnit time) { 060 return combine(Value, time); 061 } 062 063 @Override 064 public Frequency of(double magnitude) { 065 return new ImmutableFrequency(magnitude, toBaseUnits(magnitude), this); 066 } 067 068 @Override 069 public Frequency ofBaseUnits(double baseUnitMagnitude) { 070 return new ImmutableFrequency(fromBaseUnits(baseUnitMagnitude), baseUnitMagnitude, this); 071 } 072 073 @Override 074 public Frequency zero() { 075 return (Frequency) super.zero(); 076 } 077 078 @Override 079 public Frequency one() { 080 return (Frequency) super.one(); 081 } 082 083 @Override 084 public MutFrequency mutable(double initialMagnitude) { 085 return new MutFrequency(initialMagnitude, toBaseUnits(initialMagnitude), this); 086 } 087 088 @Override 089 public VelocityUnit<FrequencyUnit> per(TimeUnit time) { 090 return VelocityUnit.combine(this, time); 091 } 092 093 /** 094 * Creates a ratio unit between this unit and an arbitrary other unit. 095 * 096 * @param other the other unit 097 * @param <U> the type of the other unit 098 * @return the ratio unit 099 */ 100 public <U extends Unit> PerUnit<FrequencyUnit, U> per(U other) { 101 return PerUnit.combine(this, other); 102 } 103 104 /** 105 * Converts a measurement value in terms of another unit to this unit. 106 * 107 * @param magnitude the magnitude of the measurement in terms of the other unit 108 * @param otherUnit the other unit 109 * @return the value of the measurement in terms of this unit 110 */ 111 public double convertFrom(double magnitude, FrequencyUnit otherUnit) { 112 return fromBaseUnits(otherUnit.toBaseUnits(magnitude)); 113 } 114}