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