Suggestions for WPILib Documentation Changes

Inspired by this thread, I’ve decided to see if any of the community has an unheard requests of any documentation related changes. The past year, we have been pushing forward with many structuring, restructuring, translations, simulation, advanced controls documentation.

Questions

  • What do you want added or changed to the documentation?
  • What could be improved?
  • What could be removed?

Current Focus for 2022

  • Increased vendor integration into Zero to Robot
  • Further support for accessibility and ease of contribution
  • Reorganization to support a more clear structure and remove redundancy
  • More documentation on Advanced Gradle Configurations
  • Homepage Redesign to support a “Flow” based model.

Current Can’t-Dos

  • Theme Changes
    • Blocked by other themes not having Right-To-Left support
  • Removing the Gradient
    • frc-events is still using the gradient, waiting on approval.

Thanks!

4 Likes

image
The fact that this section is below all of the other programming sections makes it easy to not utilize them. For instance, as somebody who more or less reads the docs cover-to-cover (that is, top-to-bottom here), I read Advanced Programming/Advanced Controls first, but really the Examples and Tutorials/Trajectory Tutorial page would have been a better introduction to the topics (which refers to the former where necessary).

A couple of ideas to help with this:

  • Since the examples can be very useful but aren’t super discoverable, perhaps there should be more mentions to them throughout the docs, e.g. emphasizing the Encoder example in the encoder software documentation.
  • Somehow move the two programming tutorials up. For anyone like me who reads the docs from top to bottom for the first time, this may be a more logical order to process them in.
6 Likes

I would like to see better documentation of how exactly to implement the more advanced features of WPILib into the command-based structure. We’ve been doing command-based for most of the team’s history and we really like it, but I’ve always found the documentation a bit lacking in regards to how to use the rest of WPILib’s features in the context of the command-based structure.

For example, the trajectory tutorial touches on it, and even has you make a full drive subsystem, but then the RamseteCommand is made directly in GetAutonomousCommand instead of having it be done in a separate command class. If we were to implement it in a command, what would we put in each function? Is the RamseteCommand a Command itself? If so, does it have an End and IsFinished condition? I’m pretty sure we can figure it out, but it’s a little frustrating when Command-based seems to be the recommended way to structure robot code.

6 Likes

The MathUtil.java class is really awesome for creating turrets with wrapping and dead zones. It turned a good chunk of our turret code into a 1-liner using the inputModulous inside the clamp function. Worth having documented somewhere IMO, wish we know about it sooner.

It is a tricky line to walk between providing command and non-command examples. I agree that there should be more command examples. I am working on one right now in fact. What things in addition to trajectory have you struggled with in command based?

You can take a look at our code (especially if you are using CTRE HW) as an example of how to set command based up in the drive subsystem.

3 Likes

I desperately need better documentation and examples for gradlerio. As a gradle neophyte I can’t make head nor tail of what is going on in build.gradle. What seem like simple changes typically take me hours to research and often I fail and have to ask for help. It happened again today.

One problem seems to be that gradlerio introduces a whole new set of idioms over top of gradle such that examples that I find of how to do things in gradle don’t work for wpilibj. The gradlerio approach makes it really easy to do “the normal thing” and practically impossible (for me, anyway) to figure out how to do anything even slightly different, though once you know how, it usually doesn’t take very much code to accomplish what is needed.

The only examples for gradlerio build.gradle scripts that I could find today were essentially what is shipped as the build.gradle script for wpilibj. Absolutely not helpful for doing anything different.

1 Like

It would help us if you could give some specific examples of somethings you are trying to do.

Sure. Today’s problem is I want to build a Java file containing the current hash of the current git commit every time I build the robot code. We did this last year for C++ (I had to get help then, too). The core of the process is the same as for C++:

def hashFileInput = file("src/main/java/frc4061/robot/generate/GitHash.java.in")
def hashFileOutput = file("src/main/java/frc4061/robot/generated/GitHash.java")

task generateGitHash() {
    description = 'Generates the git hash function'
    def getGitHash = { ->
       def stdout = new ByteArrayOutputStream()
       exec {
           commandLine 'git', 'describe', '--abbrev=8', '--dirty', '--always', '--exclude=*'
           standardOutput = stdout
       }
       return stdout.toString().trim()
    }

    outputs.file hashFileOutput
    inputs.file hashFileInput 

    outputs.upToDateWhen { false }

    doLast {
        def hash = getGitHash()
        println "Writing hash ${hash} to $hashFileOutput"

        if (hashFileOutput.exists()) {
            hashFileOutput.delete()
        }
        def read = hashFileInput .text.replace('${commit_hash}', hash)
        hashFileOutput.write(read)
    }
}

When I run gradlew generateGithash this works. So the question is simple enough: how do I attach this task as a dependency for the build task for a Java project. For C++ it was done by adding (or modifying, I don’t remember) the line in the model.components.frcUserProgram section:

          ...
          tasks.withType(CppCompile) {dependsOn generateGitHash}
                cppCompiler.args << "-Wall"
                if (targetPlatform.name == wpi.platforms.roborio) {
                    cppCompiler.define 'ARM_PLATFORM'
                } else {
                    cppCompiler.define 'X86_PLATFORM'
                }
            }
           ...

There’s no model section in the build.gradle for the java project. I’ve tried putting a dependsOn relationship on various entities mentioned but all have failed with various error messages that I can’t interpret.

So, that’s my specific problem this time. A year ago it was how to add compiler switches for C++ compiles. No amount of research that I am able to do online answers these kinds of questions. The FRC community and wpilib team is great about providing help when asked. But I always hope that if I do my own research that I’ll learn something useful in the process and it will take less time than the half hour or more it has taken to prepare this post. Unfortunately that has never been the case with ANY question I have had about modifying the build.gradle file for wpilib projects. Hence my request for better documentation and examples.

1 Like

For Java, we actually don’t do anything special relative to a normal gradle Java project. To add a dependency to the java build you just use jar.dependsOn generateGitHash. Thats exactly how task dependencies work in normal gradle as well. For Java, the only special things we have are for doing the deploy. Building is entirely standard gradle.

For C++, we have to build a lot more infrastructure that is wpilib specific. I agree there is need for some better documentation on how to hook into this setup. I’m upgrading much of gradlerios internals for 2022, and I plan on documenting a lot of the special things we do in C++. But even still, there’s a lot in there that’s necessary to make things work and we don’t always have the time to document specific things until they are asked for.

Thanks Thad. That works.

Our thought in the past has always been for at least Java to depend on Gradle’s documentation for how to modify the Java end of the build. We likely could do a better job of stating that we don’t customize anything there, and add a few samples for things like generating a file, but we don’t want to just bring in a copy of all the gradle docs.

1 Like

I would find that very helpful. Just knowing that the normal Java gradle documents apply would be a good start, since I had brought along all my notions about heavy customization from my experience with C++ last year.

After some additional work on the code today I ended up in a state where compilation of my source file that referenced GitHash.java failed because the file didn’t exist. My guess is that gradle was scheduling the generateGitHash task after the compileJava task on those runs. I changed jar.dependsOn to compileJava.dependsOn and then it worked. Not a complaint – I just wanted to document that in case anyone else runs across this.

One thing that I think might be helpful for teams moving forward, is early warning about what direction the library is looking to move toward. For example, in recent years there’s been an emphasis on composition over inheritance, which is great from an architecture standpoint, but made more difficult by the current setup of how Sendable is so completely integrated with everything - when my team was attempting to make some abstraction layers, we ran into issues because there was (for instance) no base class that’s both Sendable and a SpeedController, so we ended up rolling our own. When we attempted to make a pull request to ease use, it took a year (with regular rebasing) for it to be fully rejected with a message of “we’re not planning on doing it this way”, which felt like a waste of time overall.

2 Likes

Was this a documentation change or a WPILib library change?

How would you publish / issue this guidance? It seems the simplest way in this case would have been to give better feedback on this PR but if you were advocating for something more broad I would be interested in what!

The change we tried to help make, was a library change, but the “fix” for it would probably be a documentation change. (that thread seems more about GradleRIO and not about the library itself, but I didn’t see a library thread). Even something on docs.wpilib.org that says “Here’s future paths we might be taking” would be beneficial (Maybe a “2022+ Plans” page).

Better feedback would have been appreciated, since my team explained the reasoning for wanting the change and cited real-world examples. They were dismissed as “oh you should be doing XYZ instead”, which didn’t solve the use case.

I’m not trying to push the change any further, we’re using our own wrapper library for it. My main point here is to say that teams would benefit from up-front information about the plans for the library, so they don’t head down a path that won’t be accepted.

It was this PR, for context: Create Sendable Speed Controller by msoucy · Pull Request #1567 · wpilibsuite/allwpilib · GitHub

FWIW, I think Sendable does need a good hard look at some point in the future. I’m in favor of that PR, but it’s a bit like a band-aid on a gaping wound.

2 Likes

Sendable was majorly deprecated in 2019 or something and now has only initSendable(). Everything else was deprecated and will be removed for 2022 iirc.

Cool, but this further cements my point. Most of Sendable was deprecated, sure, but initSendable still exists, and so the same sort of shims will need to be made to handle those. Is there a migration path in place? If so, where is it documented? What is the plan for teams and third party developers, who may not implement initSendable now anyways? Will teams have to create wrapper functions?

This is what I’m asking for - information on the plan for WPIlib moving forward, so that teams can prepare and learn.