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.Force; 008 009/** A unit of force like {@link Units#Newtons}. */ 010public final class ForceUnit extends MultUnit<MassUnit, LinearAccelerationUnit> { 011 private static final CombinatoryUnitCache<MassUnit, LinearAccelerationUnit, ForceUnit> cache = 012 new CombinatoryUnitCache<>(ForceUnit::new); 013 014 ForceUnit(MassUnit mass, LinearAccelerationUnit acceleration) { 015 super( 016 mass.isBaseUnit() && acceleration.isBaseUnit() 017 ? null 018 : combine(mass.getBaseUnit(), acceleration.getBaseUnit()), 019 mass, 020 acceleration); 021 } 022 023 ForceUnit( 024 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 mass and (linear) acceleration to form a unit of force. 034 * 035 * @param mass the unit of mass 036 * @param acceleration the unit of acceleration 037 * @return the combined unit of force 038 */ 039 public static ForceUnit combine(MassUnit mass, LinearAccelerationUnit acceleration) { 040 return cache.combine(mass, acceleration); 041 } 042 043 @Override 044 public ForceUnit getBaseUnit() { 045 return (ForceUnit) super.getBaseUnit(); 046 } 047 048 /** 049 * Multiplies this force unit by a unit of distance to create a unit of torque. 050 * 051 * @param distance the unit of distance 052 * @return the combined torque unit 053 */ 054 public TorqueUnit multAsTorque(DistanceUnit distance) { 055 return TorqueUnit.combine(distance, this); 056 } 057 058 // TODO: Add a multAsEnergy equivalent 059 060 @Override 061 public Force of(double magnitude) { 062 return new Force(magnitude, toBaseUnits(magnitude), this); 063 } 064 065 @Override 066 public Force ofBaseUnits(double baseUnitMagnitude) { 067 return new Force(toBaseUnits(baseUnitMagnitude), baseUnitMagnitude, this); 068 } 069 070 @Override 071 public Force zero() { 072 return (Force) super.zero(); 073 } 074 075 @Override 076 public Force one() { 077 return (Force) super.one(); 078 } 079 080 @Override 081 public VelocityUnit<ForceUnit> per(TimeUnit time) { 082 return VelocityUnit.combine(this, time); 083 } 084 085 /** 086 * Creates a ratio unit between this unit and an arbitrary other unit. 087 * 088 * @param other the other unit 089 * @param <U> the type of the other unit 090 * @return the ratio unit 091 */ 092 public <U extends Unit> PerUnit<ForceUnit, U> per(U other) { 093 return PerUnit.combine(this, other); 094 } 095 096 /** 097 * Converts a measurement value in terms of another unit to this unit. 098 * 099 * @param magnitude the magnitude of the measurement in terms of the other unit 100 * @param otherUnit the other unit 101 * @return the value of the measurement in terms of this unit 102 */ 103 public double convertFrom(double magnitude, ForceUnit otherUnit) { 104 return fromBaseUnits(otherUnit.toBaseUnits(magnitude)); 105 } 106}