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 static edu.wpi.first.units.Units.Joules; 008import static edu.wpi.first.units.Units.Seconds; 009 010import edu.wpi.first.units.measure.Power; 011 012/** 013 * Unit of power dimension. 014 * 015 * <p>This is the base type for units of power dimension. It is also used to specify the dimension 016 * for {@link Measure}: <code>Measure<PowerUnit></code>. 017 * 018 * <p>Actual units (such as {@link Units#Watts} and {@link Units#Horsepower}) can be found in the 019 * {@link Units} class. 020 */ 021public final class PowerUnit extends PerUnit<EnergyUnit, TimeUnit> { 022 private static final CombinatoryUnitCache<EnergyUnit, TimeUnit, PowerUnit> cache = 023 new CombinatoryUnitCache<>(PowerUnit::new); 024 025 PowerUnit(EnergyUnit energy, TimeUnit time) { 026 super( 027 energy.isBaseUnit() && time.isBaseUnit() 028 ? null 029 : combine(energy.getBaseUnit(), time.getBaseUnit()), 030 energy, 031 time); 032 } 033 034 PowerUnit( 035 PowerUnit baseUnit, 036 UnaryFunction toBaseConverter, 037 UnaryFunction fromBaseConverter, 038 String name, 039 String symbol) { 040 super(baseUnit, toBaseConverter, fromBaseConverter, name, symbol); 041 } 042 043 /** 044 * Combines an energy and a time unit to form a unit of power. 045 * 046 * @param energy the unit of energy 047 * @param period the unit of time 048 * @return the combined unit of power 049 */ 050 public static PowerUnit combine(EnergyUnit energy, TimeUnit period) { 051 return cache.combine(energy, period); 052 } 053 054 /** 055 * Combines voltage and current into power. 056 * 057 * @param voltage the unit of voltage 058 * @param current the unit of current 059 * @return the combined unit of power 060 */ 061 public static PowerUnit combine(VoltageUnit voltage, CurrentUnit current) { 062 return combine( 063 new EnergyUnit( 064 Joules, 065 voltage.toBaseUnits(1) * current.toBaseUnits(1), 066 voltage.name() + "-" + current.name(), 067 voltage.symbol() + "*" + current.symbol()), 068 Seconds); 069 } 070 071 /** 072 * Combines voltage and current into power. 073 * 074 * @param current the unit of current 075 * @param voltage the unit of voltage 076 * @return the combined unit of power 077 */ 078 public static PowerUnit combine(CurrentUnit current, VoltageUnit voltage) { 079 return combine(voltage, current); 080 } 081 082 /** 083 * Combines angular velocity and torque into power. Useful when dealing with motors and flywheels. 084 * 085 * @param angularVelocity the unit of angular velocity 086 * @param torque the unit of torque 087 * @return the combined unit of power 088 */ 089 public static PowerUnit combine(AngularVelocityUnit angularVelocity, TorqueUnit torque) { 090 return combine( 091 new EnergyUnit(Joules, angularVelocity.toBaseUnits(1) * torque.toBaseUnits(1), "", ""), 092 Seconds); 093 } 094 095 /** 096 * Combines angular velocity and torque into power. Useful when dealing with motors and flywheels. 097 * 098 * @param torque the unit of torque 099 * @param angularVelocity the unit of angular velocity 100 * @return the combined unit of power 101 */ 102 public static PowerUnit combine(TorqueUnit torque, AngularVelocityUnit angularVelocity) { 103 return combine(angularVelocity, torque); 104 } 105 106 @Override 107 public PowerUnit getBaseUnit() { 108 return (PowerUnit) super.getBaseUnit(); 109 } 110 111 @Override 112 public Power of(double magnitude) { 113 return new Power(magnitude, toBaseUnits(magnitude), this); 114 } 115 116 @Override 117 public Power ofBaseUnits(double baseUnitMagnitude) { 118 return new Power(fromBaseUnits(baseUnitMagnitude), baseUnitMagnitude, this); 119 } 120 121 @Override 122 public Power zero() { 123 return (Power) super.zero(); 124 } 125 126 @Override 127 public Power one() { 128 return (Power) super.one(); 129 } 130 131 @Override 132 public VelocityUnit<PowerUnit> per(TimeUnit time) { 133 return VelocityUnit.combine(this, time); 134 } 135 136 /** 137 * Creates a ratio unit between this unit and an arbitrary other unit. 138 * 139 * @param other the other unit 140 * @param <U> the type of the other unit 141 * @return the ratio unit 142 */ 143 public <U extends Unit> PerUnit<PowerUnit, U> per(U other) { 144 return PerUnit.combine(this, other); 145 } 146 147 /** 148 * Converts a measurement value in terms of another power unit to this unit. 149 * 150 * @param magnitude the magnitude of the measurement in terms of the other power unit 151 * @param otherUnit the other power unit 152 * @return the value of the measurement in terms of this unit 153 */ 154 public double convertFrom(double magnitude, PowerUnit otherUnit) { 155 return fromBaseUnits(otherUnit.toBaseUnits(magnitude)); 156 } 157}