Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wpiunits] EnergyUnit and VoltageUnit reworked as not BaseUnits. Added more generated divs and times for existing Dimensions #7473

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions wpiunits/generate_units.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,11 @@ def output(output_dir, outfn: str, contents: str):
},
"AngularVelocity": {
"base_unit": "RadiansPerSecond",
"multiply": {"Time": "Angle", "Frequency": "AngularAcceleration"},
"multiply": {
"Time": "Angle",
"Frequency": "AngularAcceleration",
"Torque": "Power",
},
"divide": {"Time": "AngularAcceleration"},
"extra": inspect.cleandoc(
"""
Expand Down Expand Up @@ -222,7 +226,13 @@ def output(output_dir, outfn: str, contents: str):
"multiply": {
"Time": "Energy",
},
"divide": {"Voltage": "Current", "Current": "Voltage", "Energy": "Frequency"},
"divide": {
"Voltage": "Current",
"Current": "Voltage",
"Energy": "Frequency",
"Torque": "AngularVelocity",
"AngularVelocity": "Torque",
},
},
"Resistance": {
"base_unit": "Ohms",
Expand Down Expand Up @@ -258,7 +268,7 @@ def output(output_dir, outfn: str, contents: str):
},
"Torque": {
"base_unit": "NewtonMeters",
"multiply": {},
"multiply": {"AngularVelocity : Power"},
"divide": {"Distance": "Force", "Force": "Distance"},
},
"Velocity": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

package edu.wpi.first.units;

import static edu.wpi.first.units.Units.Watts;

import edu.wpi.first.units.measure.AngularVelocity;
import edu.wpi.first.units.measure.ImmutableAngularVelocity;
import edu.wpi.first.units.measure.MutAngularVelocity;
Expand Down Expand Up @@ -72,6 +74,24 @@ public MutAngularVelocity mutable(double initialMagnitude) {
return new MutAngularVelocity(initialMagnitude, toBaseUnits(initialMagnitude), this);
}

/**
* Constructs a unit of power equivalent to this unit of angular velocity multiplied by another
* unit of torque. For example, {@code NewtonMeters.times(RadiansPerSecond)} will return a unit of
* power equivalent to one Watt.
*
* @param torque the unit of torque
* @param name the name of the resulting unit of power
* @param symbol the symbol used to represent the unit of power
* @return the power unit
*/
public PowerUnit mult(TorqueUnit torque, String name, String symbol) {
double baseUnitEquivalent = torque.toBaseUnits(1) / this.toBaseUnits(1);
UnaryFunction toBaseConverter = x -> x * baseUnitEquivalent;
UnaryFunction fromBaseConverter = x -> x / baseUnitEquivalent;
PowerUnit powerUnit = new PowerUnit(Watts, toBaseConverter, fromBaseConverter, name, symbol);
return Units.derive(powerUnit).named(name).symbol(symbol).make();
}

@Override
public AngularAccelerationUnit per(TimeUnit period) {
return AngularAccelerationUnit.combine(this, period);
Expand Down
6 changes: 0 additions & 6 deletions wpiunits/src/main/java/edu/wpi/first/units/BaseUnits.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,9 @@ private BaseUnits() {
/** The standard "unitless" unit. */
public static final DimensionlessUnit Value = new DimensionlessUnit(null, 1, "<?>", "<?>");

/** The standard unit of voltage, volts. */
public static final VoltageUnit VoltageUnit = new VoltageUnit(null, 1, "Volt", "V");

/** The standard unit of electric current, amperes. */
public static final CurrentUnit CurrentUnit = new CurrentUnit(null, 1, "Amp", "A");

/** The standard unit of energy, joules. */
public static final EnergyUnit EnergyUnit = new EnergyUnit(null, 1, "Joule", "J");

/** The standard unit of temperature, kelvin. */
public static final TemperatureUnit TemperatureUnit =
new TemperatureUnit(null, x -> x, x -> x, "Kelvin", "K");
Expand Down
18 changes: 14 additions & 4 deletions wpiunits/src/main/java/edu/wpi/first/units/CurrentUnit.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

package edu.wpi.first.units;

import static edu.wpi.first.units.Units.Watts;

import edu.wpi.first.units.measure.Current;
import edu.wpi.first.units.measure.ImmutableCurrent;
import edu.wpi.first.units.measure.MutCurrent;
Expand Down Expand Up @@ -43,12 +45,20 @@ public CurrentUnit getBaseUnit() {
* milliwatt, and so on.
*
* @param voltage the voltage unit to multiply by
* @param name the name of the resulting unit of power
* @param symbol the symbol used to represent the unit of power
* @return the power unit
*/
public PowerUnit mult(VoltageUnit voltage, String name, String symbol) {
return Units.derive(PowerUnit.combine(voltage, this)).named(name).symbol(symbol).make();
public PowerUnit mult(VoltageUnit voltage) {
double baseUnitEquivalent = voltage.toBaseUnits(1) * this.toBaseUnits(1);
UnaryFunction toBaseConverter = x -> x * baseUnitEquivalent;
UnaryFunction fromBaseConverter = x -> x / baseUnitEquivalent;
PowerUnit powerUnit =
new PowerUnit(
Watts,
toBaseConverter,
fromBaseConverter,
this.name() + "-" + voltage.name(),
this.symbol() + "*" + voltage.symbol());
return powerUnit;
}

@Override
Expand Down
10 changes: 9 additions & 1 deletion wpiunits/src/main/java/edu/wpi/first/units/DistanceUnit.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,13 @@ public TorqueUnit multAsTorque(ForceUnit force) {
return TorqueUnit.combine(this, force);
}

// TODO: Add a multAsEnergy equivalent
/**
* Multiplies this distance unit by a unit of force to create a unit of energy.
*
* @param force the unit of force
* @return the combined energy unit
*/
public EnergyUnit multAsEnergy(ForceUnit force) {
return EnergyUnit.combine(force, this);
}
}
91 changes: 55 additions & 36 deletions wpiunits/src/main/java/edu/wpi/first/units/EnergyUnit.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,19 @@
* <p>Actual units (such as {@link Units#Joules} and {@link Units#Kilojoules}) can be found in the
* {@link Units} class.
*/
public final class EnergyUnit extends Unit {
public final class EnergyUnit extends MultUnit<ForceUnit, DistanceUnit> {
private static final CombinatoryUnitCache<ForceUnit, DistanceUnit, EnergyUnit> cache =
new CombinatoryUnitCache<>(EnergyUnit::new);

EnergyUnit(ForceUnit force, DistanceUnit distance) {
super(
force.isBaseUnit() && distance.isBaseUnit()
? null
: combine(force.getBaseUnit(), distance.getBaseUnit()),
force,
distance);
}

EnergyUnit(
EnergyUnit baseUnit,
UnaryFunction toBaseConverter,
Expand All @@ -27,46 +39,20 @@ public final class EnergyUnit extends Unit {
super(baseUnit, toBaseConverter, fromBaseConverter, name, symbol);
}

EnergyUnit(EnergyUnit baseUnit, double baseUnitEquivalent, String name, String symbol) {
super(baseUnit, baseUnitEquivalent, name, symbol);
}

@Override
public EnergyUnit getBaseUnit() {
return (EnergyUnit) super.getBaseUnit();
}

/**
* Combines this unit of energy with a unit of time to create a unit of power.
*
* @param period the period of the change in energy
* @return the combined unit of power
*/
@Override
public PowerUnit per(TimeUnit period) {
return PowerUnit.combine(this, period);
}

/**
* Creates a ratio unit between this unit and an arbitrary other unit.
* Combines a force and distance to form a unit of energy.
*
* @param other the other unit
* @param <U> the type of the other unit
* @return the ratio unit
* @param force the unit of force
* @param distance the unit of distance
* @return the combined unit of energy
*/
public <U extends Unit> PerUnit<EnergyUnit, U> per(U other) {
return PerUnit.combine(this, other);
public static EnergyUnit combine(ForceUnit force, DistanceUnit distance) {
return cache.combine(force, distance);
}

/**
* Converts a measurement value in terms of another unit to this unit.
*
* @param magnitude the magnitude of the measurement in terms of the other unit
* @param otherUnit the other unit
* @return the value of the measurement in terms of this unit
*/
public double convertFrom(double magnitude, EnergyUnit otherUnit) {
return fromBaseUnits(otherUnit.toBaseUnits(magnitude));
@Override
public EnergyUnit getBaseUnit() {
return (EnergyUnit) super.getBaseUnit();
}

@Override
Expand All @@ -89,8 +75,41 @@ public Energy one() {
return (Energy) super.one();
}

/**
* Converts a measurement value in terms of another unit to this unit.
*
* @param magnitude the magnitude of the measurement in terms of the other unit
* @param otherUnit the other unit
* @return the value of the measurement in terms of this unit
*/
public double convertFrom(double magnitude, EnergyUnit otherUnit) {
return fromBaseUnits(otherUnit.toBaseUnits(magnitude));
}

@Override
public MutEnergy mutable(double initialMagnitude) {
return new MutEnergy(initialMagnitude, toBaseUnits(initialMagnitude), this);
}

/**
* Combines this unit of energy with a unit of time to create a unit of power.
*
* @param period the period of the change in energy
* @return the combined unit of power
*/
@Override
public PowerUnit per(TimeUnit period) {
return PowerUnit.combine(this, period);
}

/**
* Creates a ratio unit between this unit and an arbitrary other unit.
*
* @param other the other unit
* @param <U> the type of the other unit
* @return the ratio unit
*/
public <U extends Unit> PerUnit<EnergyUnit, U> per(U other) {
return PerUnit.combine(this, other);
}
}
10 changes: 9 additions & 1 deletion wpiunits/src/main/java/edu/wpi/first/units/ForceUnit.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,15 @@ public TorqueUnit multAsTorque(DistanceUnit distance) {
return TorqueUnit.combine(distance, this);
}

// TODO: Add a multAsEnergy equivalent
/**
* Multiplies this force unit by a unit of distance to create a unit of energy.
*
* @param distance the unit of distance
* @return the combined energy unit
*/
public EnergyUnit multAsEnergy(DistanceUnit distance) {
return EnergyUnit.combine(this, distance);
}

@Override
public Force of(double magnitude) {
Expand Down
89 changes: 35 additions & 54 deletions wpiunits/src/main/java/edu/wpi/first/units/PowerUnit.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

package edu.wpi.first.units;

import static edu.wpi.first.units.Units.Joules;
import static edu.wpi.first.units.Units.Seconds;
import static edu.wpi.first.units.Units.Amps;

import edu.wpi.first.units.measure.ImmutablePower;
import edu.wpi.first.units.measure.MutPower;
Expand Down Expand Up @@ -53,58 +52,6 @@ public static PowerUnit combine(EnergyUnit energy, TimeUnit period) {
return cache.combine(energy, period);
}

/**
* Combines voltage and current into power.
*
* @param voltage the unit of voltage
* @param current the unit of current
* @return the combined unit of power
*/
public static PowerUnit combine(VoltageUnit voltage, CurrentUnit current) {
return combine(
new EnergyUnit(
Joules,
voltage.toBaseUnits(1) * current.toBaseUnits(1),
voltage.name() + "-" + current.name(),
voltage.symbol() + "*" + current.symbol()),
Seconds);
}

/**
* Combines voltage and current into power.
*
* @param current the unit of current
* @param voltage the unit of voltage
* @return the combined unit of power
*/
public static PowerUnit combine(CurrentUnit current, VoltageUnit voltage) {
return combine(voltage, current);
}

/**
* Combines angular velocity and torque into power. Useful when dealing with motors and flywheels.
*
* @param angularVelocity the unit of angular velocity
* @param torque the unit of torque
* @return the combined unit of power
*/
public static PowerUnit combine(AngularVelocityUnit angularVelocity, TorqueUnit torque) {
return combine(
new EnergyUnit(Joules, angularVelocity.toBaseUnits(1) * torque.toBaseUnits(1), "", ""),
Seconds);
}

/**
* Combines angular velocity and torque into power. Useful when dealing with motors and flywheels.
*
* @param torque the unit of torque
* @param angularVelocity the unit of angular velocity
* @return the combined unit of power
*/
public static PowerUnit combine(TorqueUnit torque, AngularVelocityUnit angularVelocity) {
return combine(angularVelocity, torque);
}

@Override
public PowerUnit getBaseUnit() {
return (PowerUnit) super.getBaseUnit();
Expand Down Expand Up @@ -135,6 +82,40 @@ public MutPower mutable(double initialMagnitude) {
return new MutPower(initialMagnitude, toBaseUnits(initialMagnitude), this);
}

/**
* Constructs a unit of voltage equivalent to this unit of power divided by another unit of
* current. For example, {@code Watts.per(Amps)} will return a unit of power equivalent to one
* Volt.
*
* @param current the current unit to multiply by
* @return the power unit
*/
public VoltageUnit per(CurrentUnit current) {
return VoltageUnit.combine(this, current);
}

/**
* Constructs a unit of current equivalent to this unit of power divided by another unit of
* voltage. For example, {@code Watts.per(Volts)} will return a unit of power equivalent to one
* Amp.
*
* @param voltage the voltage unit to multiply by
* @return the power unit
*/
public CurrentUnit per(VoltageUnit voltage) {
double baseUnitEquivalent = this.toBaseUnits(1) / voltage.toBaseUnits(1);
UnaryFunction toBaseConverter = x -> x * baseUnitEquivalent;
UnaryFunction fromBaseConverter = x -> x / baseUnitEquivalent;
CurrentUnit currentUnit =
new CurrentUnit(
Amps,
toBaseConverter,
fromBaseConverter,
this.name() + " per " + voltage.name(),
this.symbol() + "/" + voltage.symbol());
return Units.derive(currentUnit).make();
}

@Override
public VelocityUnit<PowerUnit> per(TimeUnit time) {
return VelocityUnit.combine(this, time);
Expand Down
Loading
Loading