Jump to content

How do you handle project wide constants?


mje

Recommended Posts

I was wondering how each of you handle named constants in LabVIEW. Basically these are values that never change during execution, but I might want to edit their value in the IDE. The C equivalent would be a #define statement in a .h file if we were talking about global scope.

I've taken to using LV2 globals (or if I'm really lazy, a normal global), but there's of course overhead in both cases since there's some kind of referencing going on relative to a static constant.

Lookup tables are another possibility, but then the overhead is even larger because in addition to the referencing to another VI to do the lookup, you have the actual lookup logic to contend with. Too much for a constant value if you ask me.

I've often thought about using literal constants on the diagram, where the labels are decorated with special tags I can search for, but I have no experience in how maintainable code like that is. Changing the type of a named constant would seem particularly prone to errors in code. Anyone ever attempt this?

It would be really nice if in addition to {Control, Typedef, Strict Typedef} ctl files, we were also able to define a Constant which would not allow the value to be mutated outside of editing the actual *.ctl (might have to put that one in the idea exchange). But that one's more of pipe dream, how have you handled named constants historically?

Link to comment

I've used functional globals, however I've used and read good argument for using global variables. Global variables can contain constants kept in controls with the value set as the default. You then have one VI to go to for all of your constant values. I would recommend the FG over the global if you are going to access the value frequently, but if it's something that you are going to read once during initialization and never again (e.g., IP address of target system) then a global would be appropriate.

If it's a value that never changes and you don't load, a VI with a constant in it could be set to inline, thus providing the same (similar?) overhead as a constant with the benefit of changing the value one place.

Tim

  • Like 2
Link to comment

Something I've done in the past is to drop the constant value on the block diagram of a new VI, then save the VI as something like "Constant - Spreadsheet Password.vi" and that's that. This does have the downside of requiring one VI per constant, but you could just as well merge all of them with a case structure and a typedef'd enum.

  • Like 2
Link to comment

I am down with Tim_S here, IMO that's a perfect use case for Global Variables - why? because anything else (FGV, MAPs) seems like much too hard work.

I took this lead from Darren, for your use case he calls them WNRM Globals.

The cool this is that the Global acts like a config screen for developers in edit time - I find that handy.

You can even scope them if required.

You just have to get past that feeling that they are icky to use :)

Otherwise if it is a constant I will reuse - I will create a VI so I can mine it later for reuse.

Link to comment

I would recommend the FG over the global if you are going to access the value frequently...

Yes, frequency of access is a normal situation where I force a FG over a real global. When I say FG, it's not really accurate since there is never a write operation. Essentially they're just VIs acting as constants as others have implied.

If it's a value that never changes and you don't load, a VI with a constant in it could be set to inline, thus providing the same (similar?) overhead as a constant with the benefit of changing the value one place.

Brilliant, I never thought about inlining. This is infact exactly what was missing from my usage, it never occurred to me to apply inlining to these VIs.

I am down with Tim_S here, IMO that's a perfect use case for Global Variables - why? because anything else (FGV, MAPs) seems like much too hard work.

Indeed, globals are just SO EASY. But I dislike doing that because you never know when one of these VIs will end up in a tight loop once your code gets refactored for the umpteenth time.

Link to comment
Indeed, globals are just SO EASY. But I dislike doing that because you never know when one of these VIs will end up in a tight loop once your code gets refactored for the umpteenth time.

If its a constant then its never going to change - refactor it out and pass by wire into the loop.

Link to comment

I've always used a global variable for this sort of thing. If it's something that has an astronomically small chance to change I just set the default value of the control and save it. Chances are that if the value needs to change, then something else in the software needs to change anyway.

You may wish to consider voting for this idea: http://forums.ni.com/t5/LabVIEW-Idea-Exchange/Adding-CONSTs-to-LabVIEW/idi-p/942213

Link to comment

Very cool - I like this very much so I will post it here:

post-10325-0-50898000-1314698597_thumb.p

Be forwarned that globals can cause Timed Loops to finish late. I never got a good explanation as to why but testing made it clear that globals can cuase timeing issues.

Globals also do not scale well. As soon as that "constant" needs changing due to a requirements change, you may be converting to an AE in the end.

Done beating my drum,

Ben

Link to comment
There's a good illustration here.

The illustration is great, I do like it, but I still avoid using global's at present mainly due to one issue :-)

Though the Novice & Guru image in the illustration are the same there is a journey that needs to be taken to get from one to the other. When working in a team situation where there is a mix of abilities and a novice sees the use of global's, there can be an "over enthusiastic" use of them.

Curbing that uses feels a little like when I tell my daughter it it bad for her to spend to long on her Laptop and only to do a hour at a time while I sit at a PC all day long.

Link to comment

If it's a value that never changes and you don't load, a VI with a constant in it could be set to inline, thus providing the same (similar?) overhead as a constant with the benefit of changing the value one place.

Tim

I feel this is the best way to represent a project constant. It is obvious in the calling code that you are accessing a constant. Using globals, FGs, imply that data is being stored and changed. Even if you put a comment in the FG or global it still doesn't guarantee abuse of the constant, and an outside developer is left to finding all instances in the event that something goes wrong.

An inline SubVI with a constant IS an immutable object. So what is the best way to represent an immutable object (I.e project constant)? how about with an immutable object?

  • Like 1
Link to comment

A configuration file would be useful if you wanted to change the value of the constant, especially, for example, in a built application. If I want to store a constant, let say "h" or the "plank constant," I would be better served with hard coding an actual constant. Obviously that would never change, and the code damn sure communicates that. If you have an application which requires the "constant" which shouldn't even be called a "constant" to change, then use some other tool

Edited by Jon Kokott
Link to comment

OK, yes, I see and agree.

So, then, we would really like to duplicate the behavior of the constants on the Math & Scientific Constants pallette. Sure, I'd like to know how to do that, too.

It seems to me this is exactly what I described, with the exception that technically you can still edit the constant value. You can even make the icon small and everything!

  • Like 1
Link to comment
It seems to me this is exactly what I described, with the exception that technically you can still edit the constant value. You can even make the icon small and everything!

Yes, you and Tim_S both described just using a VI with a constant on the block diagram (wired to an indicator, of course), and I don't see any reason why that wouldn't work fine, especially in-lined. Sounds good to me, at least! I'm just a little slow today! :-)

  • Like 2
Link to comment

I was wondering how each of you handle named constants in LabVIEW.

The thread's title implies two different, but related questions:

Q1: How do you package constants for use in application code?

I do the same thing others have already mentioned. I wrap it in a vi and name it something like CONST_ApplicationConfigFile. Occasionally I'll put related constants in the same sub vi. Here's an example of a constant in my current app. (Yes, I realize it is not a constant as far as the compiler is concerned. From my point of view as the app developer, it is a constant, and that's my primary concern in this instance. I use this same technique for "real" constants as well.)

post-7603-0-18605300-1314737665.png

Aside from the benefit of being able to write code to generate a constant, there are a couple other reasons I prefer not using globals. First, renaming a global breaks all the references. A minor annoyance to be sure, but an annoyance nonetheless. Second, globals tend to increase coupling between components in the form of unnecessary and/or unwanted dependencies. This leads to the second question...

Q2: How do you use a project wide constant in an application?

The concept of "project wide" constants doesn't really fit into the way I build applications. The project is (hopefully) a series of well-defined components connected just enough to achieve the customer's goal. Creating an artifact (global, vi, etc.) with the intent of placing it wherever the data is needed undermines my goal of creating sustainable software.

Usually my constants are privately scoped within a single component and I'll try to design my api so other components don't need to know what the constant is. If other components do need the constant, I prefer to send a copy of the value as a message, but I have made the constant public for simplicity on the part of the calling component. I think the more correct solution would be to refactor the constant into the calling component and pass a value copy to the called component. Also, I don't let the constant be the reason for a dependency between two components.

The constant's packaging is mostly irrelevant to this question. You can create undesirable dependencies just as easily with a sub vi output as you can from a global or a FG output. From a purely functional standpoint I don't think there's much difference. On the other hand, I think globals and FGs convey a different sense of where they can be "appropriately" used than sub vis. Their intent is to make it easy to access data from different parts of an application. It would seem silly to many developers to read a global value just to pass it to another loop as message data. By wrapping the constant in a sub vi I (hopefully) break the expectation that it should be globally available.

Link to comment

So what is the best way to represent an immutable object (I.e project constant)? how about with an immutable object?

Creating a class for the LV equivalent of a #define statement seems like overkill to me, but in general immutable objects = bee's knees. :star: I use them all the time for various data classes and anywhere I want write-once, read-many functionality.

  • Like 1
Link to comment
The project is (hopefully) a series of well-defined components

As you mention, if you implement a constant then you can easily decouple that from your code by passing the data by wire from the application to the modules etc...

At the end of the day if you want to update the constant you only want to do it one spot, I can't see a difference between subVI and global in that regard, unless you wanted to add the constant to a re-use library then yes, subVI would be easier/more-common.

Maybe it does come down to expectations....

Link to comment

Here is a way to make something simular, but with the ability to be set at runtime.

Immutable objects have this capability too. Build a class with creator method(s) and getters but don't provide any setters. Once the object (not class) is created it is immutable and can only be read.

This also has the handy feature of being able to create as many objects as you want from a single class rather than having to create a separate vi for each piece of data or deal with dynamically launched vis. :D

  • Like 1
Link to comment

Thx, I do this but didn't know it had a name.

There's a decent Wikipedia article about immutable objects here.

---------------------

Here's John's WORM example rewritten (and expanded) using an immutable NumericRefnum object.

post-7603-0-06425000-1314893149_thumb.pn

In addition to being able to make an arbitrary number of objects from a single class, I think immutable objects are easier to understand and use because the initialization (or creation) method is clearly separated from the reading method.

Of course, if you *want* the FG feature of the WORM then the immutable object pattern doesn't work. (Maybe some sort of immutable class pattern would work?) Personally I prefer to avoid reference-based data, so that's not an issue for me.

ImmutableObject.zip

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.