Using wpiunits in 2024 beta development

How do I make it so wpiunits are importable in Java in developing for the 2024 beta

In a robot project? Or in allwpilib? For the latter, there’s an active PR to add it to wpimath: [wpimath] Add basic wpiunits support to wpimath by SamCarlberg Ā· Pull Request #5821 Ā· wpilibsuite/allwpilib Ā· GitHub

Allwpilib. I was going to play around with adding it to sims.

Take a look at that PR to start. The key to make it importable is adding it as a dependency to the subproject’s build.gradle (see that PR’s wpimath/build.gradle as an example).

Didn’t realize this made it into Java. How did you get around the GC overhead?

Okay. I’ve started bring the build.gradle and CMakeLists in from the PR

I’m getting this message

Project ā€˜wpimath’ is missing required source folder: ā€˜build/generated/source/proto/dev/cpp’

We minimized GC overhead by making the unit types mutable, so you reuse instances. The reference semantics can cause surprising behavior compared to an API that uses value semantics, but it’s the best we can do in Java. To do better, we’d need Java to add value classes (still a preview feature) or we’d need to move to C#, which has value types.

Does that error occur when running a Gradle build?

Yes

Okay. Tried it on a fresh branch. I just moved the build.gradle file over. The project errors were resolved, but I’m trying to create a Measure object, but no help from intellisense and no import recognition.

This branch might be a better starting point:

It’s stale and I won’t be updating it, but I’m leaving it up for reference and it’s more complete than the limited wpimath-only branch that Peter linked earlier

1 Like

I had no idea this made its way to java! Looks exciting and quite useful! Now i just need to add it to the queue for this year’s ā€œDecember nightmare of internal library updatesā€ lol. Though I do wonder how yall would recommend maintaining the spirit of this system for classes that are sometimes unitless like vectors, etc (for our team library)? Would you recommend a unit bound sub class or something to that effect?

It will depend on how you use vectors. If they’re always used with the same unit type (like distances or speeds), then you could change it to accept a Measure of that unit type.

Otherwise, you could generify the class to Vector<U extends Unit<U>> and pass in a Measure<U> for the magnitude instead of a raw number. Then you could have Vector<Distance> and Vector<Dimensionless>, for example.

Such an API could look like this:

class Vector<U extends Unit<U>> {
  Vector(Measure<U> x, Measure<U> y, Measure<U> z)
  Vector(Measure<U> magnitude, Rotation3d rotation)
  Measure<U> dot(Vector<U> other)
  Vector<U> cross(Vector<U> other)
}
1 Like

Second was my initial thought upon first seeing the api. Didn’t catch the Dimensionless unit on my initial pass through so that pretty neatly wraps up my question. Thank you so much for the response, this will be a joy to implement lol, especially given the nightmare that inconsistent units for stuff like smart motor controller onboard PIDs (and vendor deps more generally) creates, being able to have the end user tune to and use whatever units they want without having to keep track of unit consistency will be awesome!

Thank you, but the gradle file for wpimath isn’t bringing in the imports for units.

So if I just bring in the build.gradle from wpimath should the imports then work? Or do I need to bring in other build files?

Running Java: Clean language server…

cleared it up.

So to clarify. I just copied over your build.gradle and ran the clean command mentioned above

Thanks again for your help.

How does one create a Measure .

I’ve tried Units.of(Dimensionless), but nothing

You’d typically want to use someUnit.of(magnitude). For example, you could do something like this:

import edu.wpi.first.units.Measure;
import edu.wpi.first.units.Units;

Measure<Distance> dist = Units.Meters.of(5)
Measure<Mass> maxWeight = Units.Pounds.of(125);

Though I suggest using a static import for the predefined units from the Units class, so the code would look more like English:

import edu.wpi.first.units.Measure;
import static edu.wpi.first.units.Units.*;

Measure<Distance> dist = Meters.of(5)
Measure<Mass> maxWeight = Pounds.of(125);

(For reference, here’s the beta documentation article and library javadoc)

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.