Commit Graph

47 Commits

Author SHA1 Message Date
Keagan Kautzer
769ce5e9fa [wpiunits] Rename AngularMomentumUnit.mult to per (#8409)
Fixes #8408
2025-11-23 14:40:30 -08:00
Gold856
0277759d44 [wpiunits] Remove redundant if statement and inaccurate comment (#8262) 2025-09-28 16:00:35 -07:00
Tyler Veness
9ac7e286f5 [build] Upgrade Gradle plugins (#8166)
I upgraded all plugins I could see except org.ysb33r.doxygen. 2.0 made
breaking changes, and I couldn't figure out how to migrate.

Most of the changes are for suppressing new linter purification rites.
2025-08-08 23:04:02 -07:00
Peter Johnson
dd6c830768 Revert "Added parity with C++ units. (#7965)" (#7968)
This reverts commit 3dee19a435.

This was merged without sufficient review or discussion as to whether these units are value-add for the Java units library.
2025-05-11 15:08:31 -07:00
T Grinch
3dee19a435 Added parity with C++ units. (#7965)
* Added parity with C++ units.

* Update Units.java

* Update Units.java

* Formatting

* Fixed formatting

---------

Co-authored-by: thenetworkgrinch <thenetworkgrinch@users.noreply.github.com>
2025-05-10 21:04:17 -04:00
Wispy
07192285f6 [wpiunits] Add InchesPerSecondPerSecond (#7905) 2025-04-17 19:00:14 -07:00
Sam Carlberg
e52f400687 [wpiunits] Add Measure.per overloads for all known unit types (#7699)
Instead of only providing per(TimeUnit)

Useful for making conversion factors easier, eg `Inches.of(10).per(Rotation)` vs `Inches.of(10).per(Rotation.one())`

Update VelocityUnit.one() and VelocityUnit.zero() to return Velocity objects instead of generic Measure<? extends VelocityUnit<D>>; VelocityUnit is final, so the wildcard generic is unnecessary, and this makes the generated `per` functions possible for this type
2025-01-16 23:24:11 -08:00
Falon
f9b3efb712 [wpiunits] Refactor MomentOfInertiaUnit constructor to use MomentOfInertiaUnit instead of a Per<> (#7546) 2024-12-14 11:26:26 -08:00
sciencewhiz
49e3e4a0be [wpiunits] Fix deprecation javadoc for units negate (#7436)
deprecated javadoc tags aren't inherited
2024-11-27 23:03:23 -08:00
sciencewhiz
6ef5b85758 [wpiunits] Restore and deprecate divide (#7438)
It was changed to div in #7387, but 2024 used divide.
2024-11-27 23:01:26 -08:00
Vignesh Balasubramaniam
ac1836ec44 [wpiunits] Add absolute value and copy sign functionality (#7358) 2024-11-18 17:46:15 -08:00
Tim Winters
bade0a8716 [wpiunits] Use div instead of divide for kotlin compatibility (#7387) 2024-11-15 11:49:40 -07:00
sciencewhiz
71c050389a [wpiunits] Restore and deprecate measure negate (#7345)
Delegate to unaryMinus.

This ensures there's a deprecation message to help users with migration, vs just a compile error.
2024-11-06 16:07:31 -07:00
Tyler Veness
a48f3c35f4 Remove argv usage from Python scripts (#7311)
argparse will automatically read sys.argv, so we don't need to pass it
in manually. Furthermore, none of our scripts customize argv.
2024-11-02 19:09:32 -07:00
Ryan Blue
89c5d98fe9 [build] Use pathlib in wpiunits generation script (#7306)
Makes wpiunits more consistent with the other generation scripts.

Also sort imports, remove args from main.
2024-10-29 23:05:48 -07:00
Nicholas Armstrong
ac907f755a [wpiunits] Add resistance units (#7168) 2024-10-23 08:20:17 -06:00
PJ Reiniger
36e0c9d6db [build] MVP for building with bazel (#6994) 2024-10-19 09:54:49 -07:00
Sam Carlberg
9a7710ebd3 [wpiunits] Make Velocity.mult(Time) return Measure<D> (#7162)
Update code generator to allow arbitrary implementations of multiplication methods.
2024-10-03 23:19:36 -06:00
Sam Carlberg
a9b885070e [wpiunits] Java units API rewrite (#6958)
Java generics are too limited to do what we need. This refactors generic code previously in Unit and Measure into unit-specific classes that can have unit-safe math operations (notably, times and divide) that can return values in known units instead of a wildcarded Measure<?>.

Unit-specific measure implementations are automatically generated by ./wpiunits/generate_units.py, which generates generic interfaces and mutable and immutable implementations of those interfaces. These make up the bulk of the diff of this PR (approximately 9300 LOC).

This also adds units for angular and linear velocities, accelerations, and momenta; moment of inertia; and torque.
2024-09-07 10:59:29 -07:00
Gold856
b12b83aa89 Fix typos with cspell (#6972) 2024-08-17 07:44:34 -07:00
Gold856
9703142ebe [build] CMake: simplify source JAR creation and install (#6831)
Bump required minimum CMake version to 3.21.
2024-07-15 15:12:41 -07:00
Gold856
bf75c03218 [build] Clean up CMake files (#6802)
Explicitly list required components when using FindJava and FindJNI
Consolidate find_package calls for Java, JNI, and OpenCV into the root CMakeLists.txt file
Remove references to main_lib_dest
Install missing generated headers
Flatten some if statements
Use LinkMacOSGUI macro instead of hand rolling it
Stop installing OpenCV libraries and an extra ntcorejni library; OpenCV JAR will still be installed to make it easy to use
Only print platform version on Windows
Prevent GUI modules from being built when wpimath is off, which would otherwise cause a build failure
Simplify build configuration checks
Clean up fieldImages JAR creation
Place built JARs in the same subdir as installed JARs
Remove unnecessary JAR includes
Remove extra directories in target_include_directories
Improve CMake docs
2024-07-11 16:01:05 -06:00
Gold856
ae6954c78f [wpiunits] Clarify return conditions for isEquivalent (NFC) (#6727) 2024-06-09 17:54:31 -06:00
Gold856
b0cc84a9c7 [build] Upgrade to PMD 7.2.0 (#6718) 2024-06-08 22:08:23 -07:00
Gold856
b99d9c1710 Use Java 17 features (#6691)
Uses enhanced instanceof (and simplify equals methods)
Uses switch expressions and arrow labels
Seal and finalize some Shuffleboard classes

Co-authored-by: Sam Carlberg <sam@slfc.dev>
2024-06-04 21:09:10 -07:00
Gold856
72a6d22d9a [build] Organize cmake files (#6617) 2024-05-24 10:48:05 -07:00
Wispy
7fbbecb5b7 [wpiunits] Add Measure.divide(Measure<U2>) (#6611) 2024-05-15 07:22:38 -06:00
Tyler Veness
d3af27be94 [wpiunits] Fix Javadoc warning (#6614) 2024-05-12 10:25:44 -07:00
Sam Carlberg
6c9dcc157e [wpiunits] Change units to track their base unit, instead of their base class (#6342)
Unit objects now have a reference to the base unit from which they're derived. Constructing a unit object without specifying a base unit implicitly signifies that it's its own base unit, eg new Angle(null, 1, "Radian", "rad") would be the base angle unit of radians, while new Angle(Radians, 2 * PI, "Rotation", "R") would be a new angle unit based on radians.

This fixes much of the hacky code surrounding the derived unit types Velocity, Per, and Mult, but is a breaking change for any user code that defines custom unit classes or uses the anonymous unit type.
2024-05-12 06:15:56 -07:00
Wispy
39d33bfca6 [wpiunits] Adds FeetPerSecondPerSecond (#6543) 2024-04-27 21:08:13 -07:00
Nicholas Armstrong
3e6c0d0b71 [wpiunits] Add Acceleration and MOI Units (#6495) 2024-04-22 19:09:18 -07:00
vichik
e89c8c1008 [wpiunits] Add isNear function implementation (#6396)
This implementation uses a tolerance in the same units as the measure it checks.
2024-04-21 20:40:33 -07:00
DeltaDizzy
607682b687 [wpiunits] Fix Distance class javadocs to state the correct dimension (NFC) (#6363) 2024-02-19 12:58:56 -08:00
vichik
90bb6cfffa [wpiunits] Fix measure isNear function (#6313)
Now the function allows comparison between negative numbers, positive numbers or both.
2024-01-31 13:18:47 -08:00
Sam Carlberg
19f1903959 [wpiunits] Add singularized aliases for built in units (#6323) 2024-01-27 23:47:59 -08:00
Tyler Veness
77c09b9ce2 [docs] Build with JavaDoc 17 and add missing docs (#6220)
Co-authored-by: Sam Carlberg <sam.carlberg@gmail.com>
2024-01-19 23:42:09 -08:00
David Vo
a274e297cd Fix trivial errorprone warnings (NFC) (#6135) 2024-01-19 20:46:38 -08:00
Tyler Veness
4210f5635d [docs] Fix warnings about undocumented default constructors (#6151) 2024-01-04 13:57:21 -08:00
Sam Carlberg
ddf79a25d4 [wpiunits] Overload Measure.per(Time) to return Measure<Velocity> (#6018)
As opposed to returning Measure<Per<U, Time>>
Now matches the overload on Unit
2023-12-08 13:39:28 -08:00
Gold856
f5fc101fda [build] cmake: Export jars and clean up jar installs (#6014) 2023-12-06 18:28:38 -08:00
PJ Reiniger
2676b77873 Fix compilation issues that occur when building with bazel (#6008) 2023-12-04 21:18:26 -08:00
Gold856
4fcf0b25a1 [build] Apply a formatter for CMake files (#5973) 2023-11-30 16:52:21 -08:00
Andrew Gasser
95716eb0cb [wpiunits] Documentation improvements (#5932) 2023-11-23 10:57:58 -08:00
Gold856
25b7dca46b [build] Remove CMake flat install option (#5944) 2023-11-21 11:48:32 -08:00
Sam Carlberg
0ca1e9b5f9 [wpimath] Add basic wpiunits support (#5821)
To reduce the need for users to manually perform unit conversions, this allows Measure objects from wpiunits to be passed into most places in wpimath that currently expect doubles in terms of SI units like meters.

For example, users would need to know that unit conversion is required - and what the correct units are. Using units would be more difficult to write code for than just hardcoding a value or using Units.inchesToMeters.

Now, using units has no more developer overhead than using raw numbers.
2023-11-17 10:45:04 -06:00
Tyler Veness
bee32f080e [docs] Add wpiunits to JavaDocs (#5793)
Co-authored-by: Sam Carlberg <sam.carlberg@gmail.com>
2023-10-20 18:14:14 -07:00
Sam Carlberg
c065ae1fcf [wpiunits] Add subproject for a Java typesafe unit system (#5371)
# Background

Unit safety has always been a problem in WPILib. Any value corresponding to a physical measurement, such as current draw or distance traveled, is represented by a bare number with no unit tied to it; it's up to the programmer to know what units they're working and take care to remember that while working on their robot program. This leads to bugs when programmers accidentally mix units without knowing, or measure something (such as a wheel diameter) in one unit and program using another. `wpiunits` is intended to eliminate that class of bugs.

Another source of friction is the controllers and models in `wpimath` that expect all inputs to be in terms of SI units (meter, kilogram, and so on), while most FRC teams are US-based and most commonly use imperial units. wpimath does a good job of noting unit types in method names and argument names; however, it still relies on users properly converting values (and knowing they even have to do so).

# API

There are really only two core classes in this library: `Unit` and `Measure`. A `Unit` represents some dimension like distance or time. `Unit` is subclassed to define specific dimensions (eg `Distance` and `Time`) and those subclasses are instantiated to defined particular units in those dimensions, such as `Meters` and `Feet` being instances of the `Distance` class.

A `Measure` is a value tied to a particular dimension like distance and knows what unit that value is tied to. `Measure` has two implementations - one immutable and one mutable. The `Measure` interface only defines *read-only* operations; any API working with measurements should use the interface. The default implementation is `ImmutableMeasure`, which only implements those read-only operations and is useful for tracking constants. `MutableMeasure` also adds some methods that will allow for mutation of its internal state; this class is intended for use for things like sensors and controllers that track internal state and don't want to allocate new `Measure` objects every time something like `myEncoder.getDistance()` is called. However, the APIs for those methods should still only expose the read-only `Measure` interface so users can't (without casting or reflection) change the internal values.

A `Units` class provides convenient definitions for most of the commonly used unit types, such as `Meters`, `Feet`, and `Milliseconds`. I recommend static importing these units eg `import static edu.wpi.first.units.Units.Meters`) so they can be used like `Meters.of(1.234)` instead of `Units.Meters.of(1.234)`


# Examples

These examples are admittedly contrived. Users shouldn't be interacting much with measure objects themselves, since wpimath and wpilibj classes will be updated to support working with them; users will often just have to take a `Measure` output from one place (such as an encoder) and feed it as input to something else (such as a PID controller or kinematics model)

```java
// Using raw units
Encoder encoder = ...

int kPulsesPerRev = 2048;
double kWheelDiameterMeters = Units.inchesToMeters(6);
double kGearRatio = 10.86;
 // always have to remember this encoder will output in meters!
encoder.setDistancePerPulse(kWheelDiameterMeters * Math.PI / (kGearRatio * kPulsesPerRev));

Command driveDistance(double distance) {
  // have to know the distance argument needs to be in meters!
  return run(this::driveStraight).until(() -> encoder.getDistance() >= distance);
}

// Oops! This will go 16 feet, not 5!
Command driveFiveFeet = driveDistance(5);
Command driveOneMeter = driveDistance(1);
```
```java
// Using wpiunits

Encoder encoder = ...

int kPulsesPerRev = 2048;
Measure<Distance> kWheelDiameter = Inches.of(6);
double kGearRatio = 10.86;
encoder.setDistancePerPulse(kWheelDiameter.times(Math.PI).divide(kGearRatio * kPulsesPerRev));

Command driveDistance(Measure<Distance> distance) {
  // Measure#gte automatically handles unit conversions
  return run(this::driveStraight).until(() -> encoder.getDistance().gte(distance));
}

// Users HAVE to be explicit about their units
Command driveFiveFeet = driveDistance(Feet.of(5));
Command driveOneMeter = driveDistance(Meters.of(1));
```

```java
SmartDashboard.putNumber("Temperature (C)", pdp.getTemperature().in(Celsius));
SmartDashboard.putNumber("Temperature (F)", pdp.getTemperature().in(Fahrenheit));
```

```java
var InchSecond = Inch.mult(Second); // new combined unit types can be user-defined
var InchPerSecond = Inch.per(Second);

PIDController<Distance, ElectricPotential> heightController = new PIDController<>(
  /* kP */ Volts.of(0.2).per(Inch),
  /* kI */ Volts.of(0.002).per(InchSecond),
  /* kD */ Volts.of(0.008).per(InchPerSecond)
);

var elevatorTop = Feet.of(4).plus(Inches.of(6.125));
elevatorMotor.setVoltage(heightController.calculate(encoder.getDistance(), elevatorTop));
```
2023-07-23 14:18:17 -07:00