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.Velocity; 008 009/** 010 * Unit of velocity dimension that is a combination of a distance unit (numerator) and a time unit 011 * (denominator). 012 * 013 * <p>This is a generic velocity type for units that do not have discrete velocity units (eg {@link 014 * DistanceUnit} has {@link LinearVelocityUnit}, and so would not use this class). 015 * 016 * @param <D> the unit of the changing quantity, such as {@link VoltageUnit} or {@link 017 * TemperatureUnit} 018 */ 019public final class VelocityUnit<D extends Unit> extends PerUnit<D, TimeUnit> { 020 @SuppressWarnings("rawtypes") 021 private static final CombinatoryUnitCache<Unit, TimeUnit, VelocityUnit> cache = 022 new CombinatoryUnitCache<>(VelocityUnit::new); 023 024 @SuppressWarnings("unchecked") 025 VelocityUnit(D numerator, TimeUnit denominator) { 026 super( 027 numerator.isBaseUnit() && denominator.isBaseUnit() 028 ? null 029 : combine((D) numerator.getBaseUnit(), denominator.getBaseUnit()), 030 numerator, 031 denominator); 032 } 033 034 VelocityUnit( 035 VelocityUnit<D> baseUnit, 036 UnaryFunction toBaseConverter, 037 UnaryFunction fromBaseConverter, 038 String name, 039 String symbol) { 040 super(baseUnit, toBaseConverter, fromBaseConverter, name, symbol); 041 } 042 043 /** 044 * Combines a dimension unit and a unit of the period of change to create a unit of velocity. 045 * 046 * @param unit the unit of the changing dimension 047 * @param period the unit of the period of change in the velocity 048 * @param <D> the unit of the changing dimension 049 * @return the combined velocity unit 050 */ 051 @SuppressWarnings("unchecked") 052 public static <D extends Unit> VelocityUnit<D> combine(D unit, TimeUnit period) { 053 return cache.combine(unit, period); 054 } 055 056 @Override 057 public VelocityUnit<D> getBaseUnit() { 058 return (VelocityUnit<D>) super.getBaseUnit(); 059 } 060 061 /** 062 * Gets the major unit being measured (eg Meters for Meters per Second). 063 * 064 * @return the major unit 065 */ 066 public D getUnit() { 067 return numerator(); 068 } 069 070 /** 071 * Gets the period unit of the velocity, eg Seconds or Milliseconds. 072 * 073 * @return the period unit 074 */ 075 public TimeUnit getPeriod() { 076 return denominator(); 077 } 078 079 @Override 080 public Velocity<D> of(double magnitude) { 081 return new Velocity<>(magnitude, toBaseUnits(magnitude), this); 082 } 083 084 @Override 085 public Velocity<D> ofBaseUnits(double baseUnitMagnitude) { 086 return new Velocity<>(fromBaseUnits(baseUnitMagnitude), baseUnitMagnitude, this); 087 } 088 089 @Override 090 @SuppressWarnings("unchecked") 091 public Velocity<D> zero() { 092 return (Velocity<D>) super.zero(); 093 } 094 095 @Override 096 @SuppressWarnings("unchecked") 097 public Velocity<D> one() { 098 return (Velocity<D>) super.one(); 099 } 100 101 /** 102 * Combines this velocity unit with a unit of a period of change to create an acceleration unit. 103 * 104 * @param period the unit of the period of change 105 * @return the acceleration unit 106 */ 107 @Override 108 public AccelerationUnit<D> per(TimeUnit period) { 109 return AccelerationUnit.combine(this, period); 110 } 111 112 /** 113 * Creates a ratio unit between this unit and an arbitrary other unit. 114 * 115 * @param other the other unit 116 * @param <U> the type of the other unit 117 * @return the ratio unit 118 */ 119 public <U extends Unit> PerUnit<VelocityUnit<D>, U> per(U other) { 120 return PerUnit.combine(this, other); 121 } 122 123 /** 124 * Converts a measurement value in terms of another velocity unit to this unit. 125 * 126 * @param magnitude the magnitude of the measurement in terms of the other velocity unit 127 * @param otherUnit the other velocity unit 128 * @return the value of the measurement in terms of this unit 129 */ 130 public double convertFrom(double magnitude, VelocityUnit<? extends D> otherUnit) { 131 return fromBaseUnits(otherUnit.toBaseUnits(magnitude)); 132 } 133}