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