2020-2022 WPILib Feedback

In the same vein of the COTS review thread, the WPILib team is seeking feedback on the many improvements and changes made to WPILib between 2020 and 2022. This can be about the library itself or the documentation.

I like to structure this kind of feedback ask as looking for the good, the bad, and the ugly:

  • The good: What worked well? What did you find particularly beneficial to your team? What would you like to see more of?
  • The bad: What didn’t work? What did you struggle with? What would you like to see changed?
  • The ugly: What did you have to hack around to make it work for you? What made figuring out the right solution more difficult for you (e.g. wasted precious time)?

We’re working on a 5-year roadmap and plan to share it later this week. Suggestions are certainly welcome, but I’ll note that since WPILib is a volunteer effort / community project, the best way to see a feature get implemented is to implement it yourself, or get someone in the community interested in implementing it. We welcome both ideas and contributors!


The Good

Software core is solid. Really, given the scale and criticality of what it is, it’s impressive how it’s able to maintain the robustness and usability it has.

I continue to be impressed how it fills the needs of the vast majority of teams, including ours. But, simultaneously, it doesn’t get in the way when we want to something wacky and fun.

WPILib’s libraries and design patterns were the reason we were, for the first time in our team’s history, able to field a swerve drive that was highly performing, with path-planned autonomous.

A huge component to success was the fact that the FRC Discord Server is… from what I can tell… the (un)official rapid support line. Every time we ran into something a tad wonky, volunteers were there to rapidly and concisely answer my questions.

Furthermore, for the handful of issues we found, having the project not just open source, but actively and openly developed through standard tools gives me great confidence I can know its function inside and out whenever needed, and modify if our team needs something different than what it provides. I’ve done it in the past, and I am confident I’ll maintain that ability going forward.

The Bad

There were a few wonky hardware-related things at the start of the season, which were quickly rectified. Well before we got hit by em.

So not really a problem for us. Just maybe an opportunity to drive more advanced testing up front. Which is a whole ball of wax unto itself.

Integration with vendor libraries is still slightly painful. Not cuz of anything WPILib does, and not even the vendors themselves (there’s all sorts of reasons why this is). But, the fact that WPILIb isn’t able to lead the charge on more of these fronts to define and maintain good architecture is slightly disappointing to me. Granted, I don’t have a path to get the world in a state where that’s possible so… not really a great complaint.

The Ugly

The ugliest thing about WPILib: there’s more stuff there than the average high schooler can learn on their own. Even with good mentors. Heck, I’m still learning things from looking at it, and I get paid to do this for a living.

The biggest thing I believe needs to be part of future growth - a well-designed pedagogical approach to learning what’s there, and how to apply it to the average robot.

TL;DR I can’t think of actual bad stuff. Just growth opportunities.



Swerve worked really well for us, and we (as in my brother) were able to understand everything that WPILib offers for swerve, like its kinematics and odometry, even though our previous swerve programmer isn’t with us and passed almost no knowledge down. In fact, it’s such simple stuff with WPILib that after glancing at our swerve code I’m easily able to understand it and am confident in my ability to continue the line next year.

I also love that you guys continue to give us things like ProfiledPIDCommands, SequentialCommandGroups, and more command-based goodness. The addition of these helper commands saved us some time that we wouldn’t have had otherwise.


The lack of Swerve path planning. Luckily PathPlanner exists–though it took us a bit to find it. Other than this nothing was really “bad”, outside of the aforementioned hardware issues that were promptly fixed.


Nothing really stands out to me.

WPILib was wonderful this season. Glad that my first real season was a good year for WPILib. Thanks for your hard work!


Command based 2.0 gives this mechE monkey enough understanding to troubleshoot my student programmers code somewhat successfully.


Good software design has very little to do with writing software.


Love all of the code and examples.

Love the new DataLogManager…. A couple of features we will put in our logging wrappers for next time:

  • ability to specify the line of code doing the logging
  • ability to only log every x milliseconds
  • turn off system.out.println
  • would be great if driver station events could some be included, but assume the architecture makes this expensive/impossible.

Love the command framework…. Would like to have the command that caused the interruption passed into the interrupted method or at least be able to differentiate between the timeout, interrupting command, other. (After looking through the code… this seems very not trivial.)

Probably an NI request, but would love to simulate the FMS data more easily. Eventually we just put the alliance color stuff in the AutoInit because the “cute” stuff in the disabled periodic did strange things…. I think the FMS occasionally told us the wrong thing during a practice match. (In fairness we sub-ed in…). Also, the robot going to disabled between auto and telop was an interesting find.

All in all, the experience with WPILIB in the gradle, VSCode era has been incredibly positive!


The good:

  • Like gerthworm said above, the FRC discord is awesome and I have helped and been helped by a ton of people on there.
  • Extensive docs and documented source code. If you need to dig deep in wpilib to find something, it’s probably already written somewhere else.
  • Command based makes writing state machines super easy. Once you learn how it works, its easy to throw together a commandgroup to do what you want.
  • Very complex modeling and control algorithms being added with docs on how to use them. This year we were able to do a lot in sim and have bug free code on the robot much faster.

The bad:

  • Glass and similarly made tools seem to have issues with different sized monitors where automatically rescaling doesn’t happen if opening the application on a different size monitor. A little annoying when stuff is very large and doesn’t fit and you have to resize it.
  • Is there support for adding custom widgets to glass? How would one go about that? I think it would be useful to have docs explain how to do that if possible. One use case could be getting and setting a swerve modules state. This can be done with mechanism2d but is kind of clunky.
  • When working with state-space controls and models, I am a bit confused on how to architect my code with commands. Right now I have all my calculations happening in my subsystems periodic method. A lot of my commands just set the setpoint of the lqr and that’s it. But it seems to me that clashes with the declarative structure of commands. Shouldn’t the work be happening in the command?
  • The glass graph auto fit function should have some buffer on either side so the line doesn’t go right on the edge of the graph. Its hard to see on small screens!

The ugly:

  • C++ build times. I tried my best this year to make sure to only include what is necessary, only build one version (linux release) at a time, and try to make as many things as possible configurable through glass or a dashboard. But still, it pains me to see builds take multiple minutes of compilation. Especially making quick changes at the competition.

I want to preface this by saying I love WPILib and think it’s a great library for teaching kids.

But why oh why does the default project put C++ headers and implementation files into separate folders? This is easily the most frustrating part of developing Command based C++ with WPILib. It is incredibly annoying to constantly have to hunt for my matching file through the file browser whenever I change literally any signature.

Myself and my other industry mentors, all of whom do some amount of C++ dev, do not understand this at all, and have never seen it. Can someone enlighten me any benefit of this odd project layout?


As a WPILib developer, I agree that the convention we use there is terrible and would love to see it change.


We’re considering adding that to the log analysis GUI (not written yet).

Have you looked into the DriverStationSim class?

+1, worked with two C++ teams this season and routinely saw C++ build times go past 10 minutes.

That’s how I prefer to architect command-based and non-command-based robots, actually. The subsystems should provide verbs (e.g., setSetpoint()) and getters to tell when a verb is done (e.g., atSetpoint()), then commands are the state machine glue that strings actions together.

Noted, and that’s mainly due to Eigen’s template-heavy code in wpimath, and some of the fancy linear algebra causing a lot of codegen. Hopefully C++20’s modules support will deliver us from evil… The limiting factor is Clang on macOS, based on C++ Standards Support in GCC - GNU Project and Clang - C++ Programming Language Status. MSVC has full support already.


Actually I forgot a few non-code things. Specifically WPILibPi, Shuffleboard, and Glass.


WPILibPi was wonderful. It saved us a lot of time and energy with dealing with the RIO’s rather low bandwidth for cameras, and made it possible for us to have two human cams.

Shuffleboard was a saving grace for us after we had to give up our old, custom dashboard mid-competition. I also love how easy it is to create custom widgets, like resizable text and even cargo status.

Glass was very nice for tuning our shooter’s PID. Made things much easier than using Smartdashboard’s funky graphing thing.


WPILibPi seemingly refused to save camera settings as changed in the CameraServer interface, and I had to modify it in the source config JSON. Which is weird because we’ve been able to save changes from the interface on the RIO, and even sometimes before with WPILibPi.

Not necessarily “bad” but I’d like to see a way to get the match timer in some way. It’d be useful to display that in a big number on the dashboard.


Shuffleboard should have a way to be able to change the font size of a widget, maybe even from code. It was quite annoying to create a separate widget just for making 2 numbers big.

On the same topic, Shuffleboard really needs to report errors in user-made plugins. I had to spend an hour debugging why my widget made everything else disappear, basically trying every single possible solution out there. I also had an issue with the big number widget where it wouldn’t show up, and it was all because of a missing fx:id. Adding error reporting for plugins would be useful.

There’s also no documentation on how to set up a Gradle project for plugins and widgets, and after some trying I gave up and just cloned Shuffleboard. Should definitely be some docs there.

Once again thanks for your guys’ effort and hard work. Hoping my gripes are resolved at some point!


Thats what we ended up doing and I just wasnt sure if there was a specific way. Thanks for all of the effort you guys put into the project. I really appreciate it :slight_smile:

I asked @Thad_House about this before, and he told me that WPILib itself does it due to Gradle-isms (Gradle sucks at C++). Basically, it makes publishing public headers easier because all the headers are in one spot, and there’s only headers in that spot. It also lets you keep certain headers for implementation details private by putting them in the source folder instead of the header folder.

I don’t see why that should be a requirement for examples and user programs though.

1 Like

Here’s the function for that, but even the docs say not to trust it because it can be delayed.

Unfortunately, we haven’t had a Shuffleboard maintainer for the last few years, and some bug reports have been open a while. Going forward, we may have to consider finding a new maintainer or (more likely) replacing it by adding features to Glass. The big one that comes to mind is playback, which NT4 will help solve.

For wpilib code, they do need to be separate exactly for that reason.

For user code, there is no reason, other then nobody has complained about it for user code. Not something that couldn’t be changed. To me it made more sense when designing to keep things separate, but it’s not a requirement.

It’s much more common to put source and headers together, and WPILib is the odd-one-out here. :man_shrugging:

For libraries it’s not. Most open source library code I’ve seen splits public includes from source and private includes.

1 Like

I see… Hoping Glass eventually gets support for good custom widgets in the same manner/method as Shuffleboard. Keep up the work on Glass!

1 Like