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.AngularVelocity;
008import edu.wpi.first.units.measure.ImmutableAngularVelocity;
009import edu.wpi.first.units.measure.MutAngularVelocity;
010
011/** A unit of angular velocity like {@link Units#RadiansPerSecond}. */
012public final class AngularVelocityUnit extends PerUnit<AngleUnit, TimeUnit> {
013  private static final CombinatoryUnitCache<AngleUnit, TimeUnit, AngularVelocityUnit> cache =
014      new CombinatoryUnitCache<>(AngularVelocityUnit::new);
015
016  AngularVelocityUnit(AngleUnit numerator, TimeUnit denominator) {
017    super(
018        numerator.isBaseUnit() && denominator.isBaseUnit()
019            ? null
020            : combine(numerator.getBaseUnit(), denominator.getBaseUnit()),
021        numerator,
022        denominator);
023  }
024
025  AngularVelocityUnit(
026      AngularVelocityUnit 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 an angle unit and a period of time into a unit of angular velocity.
036   *
037   * @param angle the unit of the changing angle
038   * @param time the period of the changing angle
039   * @return the combined angular velocity unit
040   */
041  public static AngularVelocityUnit combine(AngleUnit angle, TimeUnit time) {
042    return cache.combine(angle, time);
043  }
044
045  @Override
046  public AngularVelocityUnit getBaseUnit() {
047    return (AngularVelocityUnit) super.getBaseUnit();
048  }
049
050  @Override
051  public AngularVelocity of(double magnitude) {
052    return new ImmutableAngularVelocity(magnitude, toBaseUnits(magnitude), this);
053  }
054
055  @Override
056  public AngularVelocity ofBaseUnits(double baseUnitMagnitude) {
057    return new ImmutableAngularVelocity(fromBaseUnits(baseUnitMagnitude), baseUnitMagnitude, this);
058  }
059
060  @Override
061  public AngularVelocity zero() {
062    return (AngularVelocity) super.zero();
063  }
064
065  @Override
066  public AngularVelocity one() {
067    return (AngularVelocity) super.one();
068  }
069
070  @Override
071  public MutAngularVelocity mutable(double initialMagnitude) {
072    return new MutAngularVelocity(initialMagnitude, toBaseUnits(initialMagnitude), this);
073  }
074
075  @Override
076  public AngularAccelerationUnit per(TimeUnit period) {
077    return AngularAccelerationUnit.combine(this, period);
078  }
079
080  /**
081   * Creates a ratio unit between this unit and an arbitrary other unit.
082   *
083   * @param other the other unit
084   * @param <U> the type of the other unit
085   * @return the ratio unit
086   */
087  public <U extends Unit> PerUnit<AngularVelocityUnit, U> per(U other) {
088    return PerUnit.combine(this, other);
089  }
090
091  /**
092   * Converts a measurement value in terms of another unit to this unit.
093   *
094   * @param magnitude the magnitude of the measurement in terms of the other unit
095   * @param otherUnit the other unit
096   * @return the value of the measurement in terms of this unit
097   */
098  public double convertFrom(double magnitude, AngularVelocityUnit otherUnit) {
099    return fromBaseUnits(otherUnit.toBaseUnits(magnitude));
100  }
101}