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