Get/Set Refnum vs Global

On my team, we always store refnums using the Get and Set Refnum methods to store references to pieces of the robot across VIs. When I was looking at some other teams’ code, I noticed that some teams ignore the Get and Set Refnum methods and store the refnums in global variables. I can see that both work, but I would imaginge one is better than the other. Can someone with more knowledge of how the Get and Set methods work explain the pros and cons of using them over global variables?

The get/set refnum is what we refer to as a functional global. It stores data as a side-effect of its execution. It implements a name -> value lookup for some number of refnums of a given type.

Regular globals will work, but it will be more work to add one more sensor, one more motor, etc. With changes being made to the framework this year, it won’t be as necessary to use either of these … but that is for another day.

Greg McKaskle

Our code the first year of LabVIEW was weird, with shift registers and accidental feedback nodes and wires looping all over the place. The second year, we used global variables. Then we used the RefNum Registry. A few years ago we did a hybrid, using a collection of global constants to programmatically create all the various motors, sensors, pneumatic actuators, etc.

Last year we used a different kind of functional global. We combined all the RefNum values for each subsystem into a bundle in a VI full of cases for Begin, Teleop, 100 ms repeat, etc. That let us select the desired resource from a menu instead of having to spell it exactly each time we wanted to use it. We found that doing a RefNum Set was still necessary in order for Test Mode to work. RefNum Get was not used in our main code.

I’m looking forward to finding out what suggestions were implemented in the framework this year, and what unexpected improvements are waiting for us.

This could actually be really nice. I have had to help so many teams debug their code because they accidentally put an extra space or changed a capitol in a refnum name. We have actually not used refnums at all since 2010, and instead implement our own functional globals for each subsystem with a Begin, Run and End enum, because of all the troubles refnums caused, plus the speed hit involved with a string lookup table. It will be interesting to see if the new changes do anything like this, even though this season is probably our last using LabVIEW.

As for the original question, the refnums are/were good because you could access the state of any IO object from anywhere in your code. The other solutions are like you said storing all these in globals, implementing your own storage, or running wires between every VI with the object state. For FRC, refnums were the easiest way to do this it seemed, but without compiler checking for the string, it caused a lot of headache.

Just to clarify terminology, open nodes return refnums. The approach in 2009 was that you would just wire the refnum through the connector pane, possibly using clusters. No names, and not that hard, but there are a number of syntax errors that can come up.

In order to avoid concepts such as modifying a connector or building a cluster, we added the refnum registry in 2010. The benefit is that you don’t need to cluster various I/O refnums and send them to the auto and tele routines via connector. But instead, you would use a name lookup. In general, I also prefer earlier syntax checking, but this was a way to avoid several concepts. I don’t think the name lookup is very expensive, but if I were to try and avoid it, I’d choose wires over globals or functional globals.

The new framework I was eluding to is to have subsystems own I/O. Very little I/O will likely be published for use in tele or auto. Instead, it will belong to the state machines or control loops that are directed by auto and tele alike. This is similar to Command-Based programming offered by WPILib, but with distinct differences.

None of the other frameworks will be removed, but an additional complementary organizational structure will be added. I’m excited to see what teams do with it. It was covered in a Champs presentation last year, and will be a part of this season’s beta testing which gets underway any day now.

Greg McKaskle