WPILib as volunteer-run project

Part of the issue is we’ve gone from not enough docs to too many docs. I have trouble finding articles I already know the name of, and I’m a WPILib developer who is intimately familiar with the library; frc-docs’s search is polluted by too many articles, and the sidebar is organized such that it’s useless. The frc-docs project maintainer discouraged me from doing incremental refactors, in favor of a giant all-at-once refactor no one has the time to do… it’s frustrating.

Indeed. I don’t know how to fix this though, because vendors like controlling their own fiefdoms. We softened our stance on vendor examples for frc-docs a while ago (anything is better than nothing), but vendors would rather maintain their own documentation on separate sites.

Maybe FIRST needs to step in, because WPILib has no power here. We’ve tried to push standardization of CAN frames and CAN APIs before, and the only vendors on board with it are new ones because that makes it easier for them to enter the market. The incumbents consider software to be their main product differentiator and would rather maintain their marketshare via walled gardens.

I personally dislike how large the CAN motor controller APIs have gotten. They’re the same surface area as WPILib, but each organized differently, and the typical robot uses a lot of it (digital inputs, analog inputs, encoders, PID, motion profiles, current limiting, voltage set/get, current set/get).

A big reason to use those APIs is to offload as much as possible from the roboRIO, because the roboRIO is slow, and Java’s garbage collector introduces a lot of nondeterminism. Maybe the 2027 MRC will let teams move more stuff back to a central controller.

6 Likes

I’m sorry you had that experience, and we know this is certainly an area that needs improvement for us–timely feedback on PRs is important for good collaborative engagement with community contributors and avoiding the frustration you ran into. We currently have nearly 100 open PRs on allwpilib (although about half of those are in draft state) and 27 open PRs on frc-docs. I know I’m certainly guilty of letting allwpilib PRs/reviews age without good communication on review status. Speaking for myself, there’s often a few different factors that can cause this to happen: life intervenes (insufficient time), it falls off my radar, the change has debate surrounding it (or just uncertainty as to whether the proposed change is a good one), it interacts with a larger project, or we don’t have a good reviewer for it (or we do, but they got distracted). One of the early concerns with making WPILib open source was that we would be so flooded with contributions that we wouldn’t be able to keep up–while that hasn’t quite happened, reviewing contributions definitely takes time!

There are other major reasons. Note some things like current limiting aren’t really possible to do from the roboRIO. Regarding sensors, some other reasons that I’ve heard from teams: using CAN devices simplifies wiring (one daisy chain versus a bunch of separate wires, integrated sensors means there’s no need for sensor wiring at all), and the vendors provide useful GUI tools for debugging/testing (LiveWindow was WPILib’s somewhat primitive version of that for things plugged into the Rio, but it’s stagnated to the point of uselessness as teams have moved to CAN controllers). Even with a faster processor, I really don’t see teams broadly moving e.g. swerve closed loop control back onto the main robot controller with non-CAN sensor wiring. Even in FTC, it’s likely future motors will have integrated sensors, because wiring and mechanical integration of separate sensors is a barrier to teams. “Smart” motors with integrated sensors and more complex internal control capabilities is the clear future here, and I don’t see a return to the old days of having everything hooked up and driven by the robot controller.

The problem with MotorController is it’s too simple of an interface for modern team needs. Teams want (and with swerve drive, essentially need) to use the more advanced features of CAN controllers (whether that be current limiting, sensor feedback, closed loop control, current instead of voltage control, etc), and MotorController doesn’t have support for any of those. We can’t write a workable swerve drive example on top of MotorController, because the COTS swerve drive solutions use the integrated encoders of the motors, and MotorController does not provide access to that.

However, as the two major motor controller vendors have very different API shapes and a Venn Diagram of features, coming up with a common interface set for these features that feels natural to work with and eases transitions to vendor-specific APIs that grant access to the full feature set of each vendor (which is what teams will want to be able to do) is quite difficult… and then we have to get the vendors to buy into actually implementing it.

An alternative solution that some teams have implemented is motor controller wrappers–effectively creating a new API that papers over the differences between the vendors, with implementations for each vendor API. This has a couple of advantages, but has similar problems to adding interfaces, with the additional downside that it creates a larger barrier to jump over to transition to what will look like very different vendor APIs and some additional technical difficulties re: ABI safety and runtime integration.

In short, this is a hard problem with multiple tradeoffs. We see the need, but there’s not a clear path forward.

6 Likes

For which I am entirely thankful and grateful!

A lot of people in FIRST don’t realize the huge amount of effort and thought that has gone into the WPILib codebase. Every year volunteers are adding functionality, making sure that released software installs and works as intended, etc.

Thank you to the entire WPILib team!

9 Likes

Writing reliable software for a distributed system with a fallible transport medium (CAN) is also a barrier to teams, so I guess it’s a “pick your poison” situation.

1 Like

What if an interface was specified and used in examples, and then documentation could explain how the methods of this interface would relate to methods in vendor-specific APIs, perhaps also explaining the quirks of each? This interface could be created such that it makes sense for a motor controller to implement it (it has all the right methods and a reasonable name), and then in the future new vendors could make motor controllers with this API and old vendors could consider transitioning to it.

Once a generic CAN motor controller API (either interfaces or wrappers) exists, I like the idea of a documentation page describing the differences between our “generic” API/interfaces and what vendor APIs provide to ease team transition from our examples to vendor-specific APIs (although that might better live in vendor docs rather than WPILib docs). This would be particularly needed in the wrapper approach as it would likely have more major differences to vendor-specific APIs. However, it can’t just be an abstract thing, as our examples are compile-tested, and lots of teams expect to copy-paste them into their code, so we need a concrete implementation. This is one of the other challenges, as we can’t have the WPILib build depend on vendor libraries (that would create a dependency loop). The semi-obvious answer for a “common” concrete implementation would be something implemented with Rio IO, or it could be a sim-only mock implementation that’s a NOP on the Rio.

This would be a potential source of income for that group for commercial licenses. If students could leave FRC and continue to use the wpilib for external commercial work they would certainly be at an advantage over remaking it all from scratch or learning a new library or system like ROS to do the same type of things. The biggest downside is how it’s tied to one specific robot controller, but that’s also why the quality is so high I think. The hardware is mostly consistent. With commercial work also comes expanding the system out for other Linux based io controllers. The new controller is a good example of expanding the system out, but the question will be will the new controller board be commerically usable and available or not

2 Likes

That’s what almost all our existing examples do, and no one uses them because they don’t match the vendor APIs exactly; teams copy-paste from other team’s codebases instead.

We did that in the armbotoffboard, drivedistanceoffboard, elevatortrapezoidprofile, and elevatorexponentialprofile examples (see ExampleSmartMotorController), with the earliest added for the 2020 season. Teams don’t use those either because they don’t match the vendor APIs exactly.

To get teams to use it, we’d need to duplicate and shim significant chunks of vendor APIs. We’d also need some out-of-band way to notify us when vendors have changed their API and deviated from what our shims do.

I’ll second this as a big problem. I know something is in the docs but I can never find it quickly through the side bar or search when I need it. It becomes difficult to direct students to the docs when mentors familiar with them can’t even find what they are looking for.

1 Like

FRC’s unique market conditions (new programmers and AP CS support) made Java popular on the roboRIO embedded device, but the C++ port would likely get more traction in industrial settings because Java’s lack of determinism and extra overhead make it a bad choice for embedded in general. Companies select embedded platforms that are as cheap as their requirements will allow to maximize profit per item relative to salary saved from having to optimize the firmware less. That usually means selecting something that can’t handle overhead. Veteran FRC students will have to relearn everything in C++, so the knowledge transfer won’t be as good.

We could potentially write HALs for different controllers if we rewrite the HAL interface to not be so roboRIO-specific.

The path of least resistance is just rewriting the HAL to be MRC-specific instead of roboRIO-specific, but we’ll see what happens.

However, our aggressive approach to staying on the C++ bleeding edge and dropping older target platforms would be problematic for commercial users, who (as you know) generally prioritize stability over the latest features (e.g. still want stuff to work on 18.04 LTS in 2025).

4 Likes

Yea… and that mindset is precisely why commercial software tends to suck so much. Improving things costs money and is hard to make a business case for if what exists still works. If WPILib had commercial customers back in 2008, we’d probably still be stuck with that API 15 years later, unless we forked.

1 Like

This can be partially avoided by using compiled-in renditions of those features, as a library or single file.

It’s not super convenient but it does at the very least give you access to newer parts of the standard library. Unfortunately it wouldn’t unlock new compiler features like modules and whatnot.

I know for a fact it exists for generators, not sure about anything else.

We do use polyfill in a few places where target platform library support is not yet standards compliant (Mac in particular lags a bit behind the other platforms). But we were fairly early adopters of C++20 compiler features which can’t be shimmed (in particular, concepts and certain constexpr use cases).

Peter, I would like to volunteer. I have 55 years experience writing software and mentor team 7587 and am fluent in Java and C++.

How can I contact you off-list

Feel free to PM me here or on Discord.