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.ImmutableLinearAcceleration;
008import edu.wpi.first.units.measure.LinearAcceleration;
009import edu.wpi.first.units.measure.MutLinearAcceleration;
010
011/**
012 * A unit of linear acceleration like {@link edu.wpi.first.units.Units#MetersPerSecondPerSecond}.
013 */
014public final class LinearAccelerationUnit extends PerUnit<LinearVelocityUnit, TimeUnit> {
015  private static final CombinatoryUnitCache<LinearVelocityUnit, TimeUnit, LinearAccelerationUnit>
016      cache = new CombinatoryUnitCache<>(LinearAccelerationUnit::new);
017
018  LinearAccelerationUnit(LinearVelocityUnit 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  LinearAccelerationUnit(
028      LinearAccelerationUnit 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 linear velocity and time unit to form a unit of linear acceleration.
038   *
039   * @param velocity the unit of linear velocity
040   * @param period the unit of time
041   * @return the combined unit of linear acceleration
042   */
043  public static LinearAccelerationUnit combine(LinearVelocityUnit velocity, TimeUnit period) {
044    return cache.combine(velocity, period);
045  }
046
047  @Override
048  public LinearAccelerationUnit getBaseUnit() {
049    return (LinearAccelerationUnit) super.getBaseUnit();
050  }
051
052  @Override
053  public LinearAcceleration of(double magnitude) {
054    return new ImmutableLinearAcceleration(magnitude, toBaseUnits(magnitude), this);
055  }
056
057  @Override
058  public LinearAcceleration ofBaseUnits(double baseUnitMagnitude) {
059    return new ImmutableLinearAcceleration(
060        fromBaseUnits(baseUnitMagnitude), baseUnitMagnitude, this);
061  }
062
063  @Override
064  public LinearAcceleration zero() {
065    return (LinearAcceleration) super.zero();
066  }
067
068  @Override
069  public LinearAcceleration one() {
070    return (LinearAcceleration) super.one();
071  }
072
073  @Override
074  public MutLinearAcceleration mutable(double initialMagnitude) {
075    return new MutLinearAcceleration(initialMagnitude, toBaseUnits(initialMagnitude), this);
076  }
077
078  @Override
079  public VelocityUnit<LinearAccelerationUnit> per(TimeUnit time) {
080    return VelocityUnit.combine(this, time);
081  }
082
083  /**
084   * Creates a ratio unit between this unit and an arbitrary other unit.
085   *
086   * @param other the other unit
087   * @param <U> the type of the other unit
088   * @return the ratio unit
089   */
090  public <U extends Unit> PerUnit<LinearAccelerationUnit, U> per(U other) {
091    return PerUnit.combine(this, other);
092  }
093
094  /**
095   * Converts a measurement value in terms of another unit to this unit.
096   *
097   * @param magnitude the magnitude of the measurement in terms of the other unit
098   * @param otherUnit the other unit
099   * @return the value of the measurement in terms of this unit
100   */
101  public double convertFrom(double magnitude, LinearAccelerationUnit otherUnit) {
102    return fromBaseUnits(otherUnit.toBaseUnits(magnitude));
103  }
104
105  /**
106   * Gets the unit of the changing velocity. This is equivalent to {@link #numerator()} and is left
107   * for historical purposes.
108   *
109   * @return the unit of the changing velocity
110   */
111  public LinearVelocityUnit getUnit() {
112    return numerator();
113  }
114
115  /**
116   * Gets the unit of the acceleration period (how long it takes for a measured velocity to change
117   * by one unit of velocity). This is equivalent to {@link #numerator()} and is left for historical
118   * purposes.
119   *
120   * @return the unit of the acceleration period
121   */
122  public TimeUnit getPeriod() {
123    return denominator();
124  }
125}