FRC Programming, Done Right

Recently, a productive discussion was had on the FRC Discord about the spread of programming ability among teams. Many recognized that teams like 254 do better due to things such as trajectories and vision, but everyone should learn how to do this.

After some debate, we starting thinking of what we could do to help all teams raise their programming skills to become more competitive, even with bots that aren’t as mechanically sound as 971s. I came up with the idea of FRC Programming Done Right, an online guide to teach both the basics of programming in Java, C++, and Python (LabView isn’t very easy to teach textually, and it is more useful to learn text-based IMO), and good programming practices in FRC.

The guide is a work in progress right now, but over the summer I plan to make it my main focus (along with my job), but help is always wanted. If you have an aspect of programming you’re passionate about (arrays, loops, opencv, vision in general, etc) feel free to contribute. Or, if you think something can be explained better, say so! Feedback on this is going to be the most crucial part. If the writers don’t know something’s bad, we can’t fix. If you just want to see something added, open an issue.

You can find the docs here, and the github repo here

I personally think this is a great idea and will surely be keeping an eye on this project.

Vision NEEDS to be demistified. It is not hard at all to implement, and even rookie teams can implement a decent vision system.

The trickiest parts of integrating vision have nothing to do with vision…they have to do with integration.

Really great initiative!!

I would try to contribute some when I have the time.

Just one thing to consider: I am not sure writing language programming guides is as useful, there are many wonderful guides already freely available online and linking to them with some instructions about required as and relevant materials will probably be better than us re-inventing the wheel!

Integration with control loops? Can you explain some more?

This does sound like a noble cause. I’ll be seeing how I can help.

I’m not of 254, but I would guess he means integrating the camera with the vision coprocessor with the RIO. 5115 does this with a raspberry pi and a usb webcam, so we set exposure settings and the like using fswebcam (or whichever tool seems to work the best), use python and opencv for processing, and send data to the RIO with networktables. This turns into a giant headache of protocols and linux utilities, whereas just getting the data from the image is pretty simple.

I believe 254 uses an android phone for their vision; I’m interested to hear how it works.

Adding to what Brian said, integrating the two separate systems (vision and robot) can be a real pain. A channel must be set up for sending data (NetworkTables, UDP sockets, etc.) and startup scripts have to be configured on the co-processor. This isn’t extremely hard, but for a rookie team without technical mentors or programmers who have worked in Linux environments before, it becomes quite a challenge.

GRIP has managed to simplify this process quite a bit with deployment to RPi, but considering the amount of hardware out there, it’s difficult to support every possible Linux SoC that rookies may get their hands on.

*Demystify the concept of realtime

Many rookie teams, even those with students (or even mentors) who have done some programming do not understand threads and state machines etc. They wonder why their code doesn’t work when they spin-wait in Teleop. Explain the concepts, and the proper way to code, in the various FRC languages and frameworks.

Debugging

Many teams don’t know what to do when a problem occurs. Debugging should be a methodical process. Explain the built-in debugging support in the various languages (and frameworks). In cases where the framework doesn’t have full support, explain the concept of code instrumentation like monitoring for thread execution overruns, missed cycles, and jitter… and toggling an unused DO pin in each thread so you can look at the timing on a scope or logic analyzer.

Vision isn’t hard. If you’ve been doing it for a while. But then again, autonomous isn’t hard, driving straight in auto isn’t hard, and driving a specific distance in auto isn’t hard. Yet I’d say perhaps 50% of FRC teams struggle to do those things. At a minimum, to do vision correctly you need to understand:

  1. Drive encoders.
  2. Gyro.
  3. Camera, field of view, trigonometry and methods to calculate distance and angles.
  4. Vision software
  5. Communication
  6. Mechanical integration (the best coder in the world can’t do vision if they don’t understand momentum, drivetrain backlash, friction, etc etc.)

Now you need to take all of that and reteach it every year so the newest incoming batch of programmers comprehends it all and can do it by the time they are juniors or seniors.

“Vision” by itself isn’t horribly difficult - it’s all the other ‘stuff’.

FYI - differential equations aren’t all that hard either :smiley:

Consider the following timeline:

Your robot is moving at 7ft/s following a slight (2º/second) curve to the right while de-accelerating. Your camera camera captures an image with the peg vision targets. The vision processing code take 87ms to processes the image, giving you longitudinal and latitudinal offsets as well as the angle to the peg.

Assume everything above is accurate, you are well past the vision part of the problem and now in the thick of the control part of the problem. Your robot has moved over 7" since the image was taken along a complex path. Mix in the fact that you will be getting another 10-15 frames per second to continually adjust your loop against, might get hit by another robot, etc…

You can of course simplify the problem. Stop grab and process image. Rotate and move, etc. But realize that there is a spectrum of difficulty and for the most part, when given vision targets, the actual image processing is not the hardest piece of the puzzle

This is the hard (and fun) stuff.

1 Like

Just as a note, in the variables part of the document, I wouldn’t recommend discussing things like what case to use for variables.

In C++, the standard library uses snake_case for functions, while WPILib uses CamelCase, while others might prefer lowerCamelCase. There is no ‘right’ way to do this, just like the argument of whether the open brace should be on its own line or not. Personally, I use snake_case in C++ and lowerCamelCase in Java, and with the open brace on the same line for both, but others might have different opinions.

The important thing is for it to be consistent.

I’ll try and keep an eye on the project as it progresses and see if I can help. Good luck.

I would eliminate the Introduction section as it is currently. Rather good online courses and books already exist for learning Java, C++, and Python. Instead, put the FRC specific things you’re not likely to find anywhere else and focus more on the high level concepts that will help people become competitive, not on creating O’Reilly Java/C++/Python: The Good Parts (Except 95% Is Cut Out)
Of course, add in some links to good C++/Java/Python learning resources and wpilib screensteps.
I’d also put a very big warning to steer clear of C++ unless you are ready to make your life extremely difficult* for a small amount of extra performance :rolleyes:

  • builds take forever, segfaults silently crash your program, debugging is a bad eclipse GUI over gdb over ssh (annoying!), overall basically every C++ language feature comes with 20 ways to do it wrong without realizing

I would like to respectfully tell you that I disagree.

C/C++ is only a pain if you let it be a pain. If you take the time to learn what’s the safe way to do things, and what isn’t, you won’t have any problems with silent segfaults. Sure, there are many ways to go about doing something, but none of them are the same. You have to identify what is the best for your situation.

Sure, C++ might have a bigger learning curve than Java, but it’s learning curve is a lot more steady than Java’s. The basics might take a little longer to learn than Java’s, but keep in mind that a lot of people that “know” Java only know the basics. Reflection, classloading, security policies, native interfacing are all language features of Java that commonly go unrecognized, not to mention the entire JVM architecture itself.

If anything, C/C++ are the most relevant languages you can learn in your time in FRC, as this is likely what you will be dealing with if you wish to pursue embedded software engineering further. That being said, there’s nothing wrong with Java and Python.

None of the FRC languages are bad, it just depends on what your priorities are and what you want to use them for.

I would agree that C/C++ are not bad languages at all too use in FRC, but using Java with high schoolers is a bit of an advantage since many of them have taken AP Computer Science.

Intro to Java still had like 7 different prerequisite computer science classes when I took it at the College level a few years ago. Either a lot has changed since I was in high school or your area does things a lot different than they do here (AP computer science classes are even a thing that high schools have?). :rolleyes:

Personally having taken both Java and C++, I always preferred C++ because it seemed to do the same things but more simply (creating variables, managing classes, etc.), but that could also just be because I learned C++ the semester before I took Java. Either way whatever language you know works, they do basically the same things.

Back to the specific topic of this thread however, one thing I think I would like to see is more pre-built code segments available to teams, that can be searched by, and include explanations of, their use cases. For example, my team struggled literally for years to have functional encoders on our robot, even after we started using CAN Talons, the documentation wasn’t clear as to how to correctly use and configure them for use in different applications (drive-distance auton, teleop steering correction, shooter speed control, etc.). It would be great if there was just a page somewhere that provided some basic code options that teams could select based on their desired functionality and just copy and paste into their robot code. The section for PID control on this new website is a good example of the type of information teams typically find, it does a decent job at describing the concept behind PID, but completely leaves out any specific examples/details of its implementation (this is not meant to be critical of this site, as clearly it’s still under development, but it was an easy example to use for this discussion).

Having resources like that would also be particularly helpful to teams who don’t have a programming mentor (or who do but don’t have FRC-specific experience), so that a mentor with limited programming knowledge could point a student who might have some experience with programming but no FRC experience to the resources they need to be able to implement features like vision/sensors and other more advanced features.

There’s plenty of documentation out there already on the basics of programming in various languages, but I feel like there’s very little (at least that I’m aware of) as far as organized repositories on how to program specifically for FRC uses, at least beyond the provided robot default code.

[/2am rant]

Well said. It’s wandering a bit off topic here, but the way we currently attack this is by buffering up all the relevant telemetry, and then use that info, along with the processing time of the frame, and we make the captured image data relative to the telemetry when the image was taken. Is this the right approach? Is there anything else we could do ontop of it to achieve better results?

I like your code already. And concur that trying to explain naming conventions while teaching variables is a distraction.

I didn’t say C++ is bad. I said C++ is very difficult for beginners.

That’s exactly what I meant by “make your life difficult”