There is something wrong with this VI, although you wouldn't know it unless you ran it (and I should warn you that it will annoy you if you run it):
What's wrong with it is that auto grow has been disabled and there's some annoying code hidden there beyond the loop boundary. This is one of my least favorite things about LV - it allows us to hide code completely and get away with it. I don't think it should.
LV already has auto grow enabled by default to handle some of the cases which cause this issue, but I know that many many people don't like it when LV automatically plays with their BD layout (and rightly so) and auto grow only covers some of the cases, so I think we need something more encompassing and less obtrusive, and I would suggest breaking the VI if it has hidden code.
I also know that LV has warnings and VI Analyzer has tests for this, but I think this needs to be something which doesn't let you get away with it.
I think LV should break any VI which has any of the following:
Interpolate 2D Scattered uses triangulation which is fairly CPU intensive.
The most difficult part, (and the part that most of the CPU time is spent on) is defining the triangles. Once the triangles are specified, the interpolation is fairly quick (and could possibly be done on an FPGA). This is the same idea as using the scatteredInterpolant class in Matlab (see : http://www.mathworks.com/help/matlab/math/interpol
The Interpolate 2D Scattered function needs to be broken up into two pieces just like Spline Interpolant, Spline Interpolate are.
I don't know how many times I've added a case statement post-programming, but I do know that there isn't an easy way to make a tunnel the case selector. Usually I delete the tunnel and then drag the case selector down and then rewire, there should be an easier way. For loops and while loops have an easy way to index/unindex or replace with shift register, why can't a case statement be the same?
a possible improvement for the "search 1D function"
The current function searches for an element identical to the input element.
It would be useful to be able to do the opposite :
Search 1D Array : be able to search a different element
a new function or ...
the current function with an option to select : "the same element", or "a different element".
and why not (It would be also useful) an additional output with this different element.
I think it would be nice if LabVIEW was smart enough to know that when I drop a For Loop around scalar inputs it doesn't auto-index output tunnels - but rather uses Shift Registers - for matching inputs and outputs.
The common use case for this is with the Error input/output - it annoys me how it becomes an Array output.
As it is already wired, inline and not broken, dropping a For Loop around it should not break my code!
Reference or Class inputs are other use case too - I want to pass the same thing around not create an Array.
Shift registers are better than non-auto-indexed tunnels (other option) as they protect the inputs on zero iterations.
This would remove one step required for most use cases, speeding up my development experience.
I propose to replace Max & Min for two elements, which we could resize like some array functions for 3, 4, 5,... elements when you know how many you have to compare.
I actually have 5 elements coming from a bundle, I have to do this
Format into text is very useful but can become hard to edit when it has a lot of inputs. I propose, instead of one huge format string, that the programmer be allowed to put the required format next to the corresponding input. Also, the user should be allowed to enter constant strings, e.g.. \n, \t, or "Comment", and have the corresponding input field automatically grayed out.
As soon as we have more complicated data structures (e.g. clusters of arrays), a large portion of the FP real estate is
wasted taken up by borders, frames and trims, etc.
We need a palette full of "Amish" controls, indicators, and containers that eliminate all that extra baggage. We have a few controls already in the classic palette, but this needs to be expanded to include all types of controls, including graphs, containers, etc.
A flat control consists of a plain square and some text (numerical value, string, ring, boolean text, etc). A flat container is a simple borderless container. A flat graph is a simple line drawing that would look great on a b&w printer. A flat picture ring looks like the image alone.
They have a single area color and a single pixel outline, if both have the same color, the outline does not show. They can also be made transparent, of course. If we look at them in the control editor, there are only very few parts.
Now, why would that be useful?
Let's have a look a the data structure in the image. There is way too much fluff, distracting from the actual data. If we had flat objects, the same could look as the "table" below. Note that this is now the actual array of clusters, no formatting involved! It is fully operational, e.g. I can pick another enum value, uncheck the boolean, or enter data as in the cluster above.
Many years ago in LabVIEW 4, I actually made a borderless cluster container in the control editor and it looked fine, but it was difficult to use because it was nearly impossible the grab the right thing with the mouse at edit time.
The main problem of cours is that the object edges completely overlap, making targeted seletion with the mouse impossible. (For example the upper right corner pixel is the corner of an array, a cluster, another array, and an element at the same time.)
So what we need is a layer selection tool that allows us to pick what we want (similar to tools in graphics editing software). It could look similar to the context help shown in the picture with selection boxes for each line. Picking an object would show the relevant handles so we can intereact with the desired object. Another possibility would be to hover over the corner and hit a certain key to rotate trough all near elements until the right element is selected, showing it's resize handles. I am sure there are other solutions.
As a welcome side effect, redrawing such a FP is relatively cheap.
A longstanding issue with the "active plot" property is that is throws an error if fewer plots currently exist. Conversely, if we wire data containing more plots, the graph automatically adapts to that.
The main problem with this is that the order of operations matters. We need to write the value first, followed by the active plot properties. Many times we already know what kind of plots we want (color, name, etc.), even if one of the plots is only added in a later step or the terminal is written a nanosecond later due to code scheduling. Workarounds mean excessive sequentialization because we need to enforce strict order: (1) write data (2) update plot properties.
The current behavior is annoying, and there are many forum examples where that was the cause of the problem (example).
Two suggestions can address this:
(1) if an active plot property is written, and that plot does not exist yet datawise, it should be created automatically and the node returns without error. (Of course all other missing plots up to that number need to be created too, they can have default properties).
(2) Maybe there should also be a property for "number of plots" than can be written to define the number of plots.
I would like a shared memory region accessible from both RT and FPGA. LV FGPA has memory regions accessible from anywhere in the FPGA, however you need to use DMA or front panel controls to exchange the data with RT. I envision a much larger memory region within RT's memory space where RT and FPGA could peek and poke values. The user interface would be like the current FPGA implementation with a matching interface on RT.
Auto-indexing of arrays in for and while loops are a nice luxury in LabView. One option that could save much time would be a menu option to turn on conditional indexing, this would expose a boolean terminal under the auto-index icon to select if the current itteration should add the itteration to the array or skip it. From an execution standpoint there would only be a minor performance hit (could still preallocate max array size on for loops and automatically return used subset). This could also work for autoindexed in but would have less use that the autoindeded out case. I know I have built many conditional arrays inside of a for loop and it requires a case selection and a build array making the code less readable and requires time and thought. It can also be less efficient than a compiler can do.
See the example below which would run a for loop and only build array of < 0.1
It is time to put a dent in the floating point "problems" encountered by many in LV. Due to the (not so?) well-known limitations of floating point representations, comparisons can often lead to surprising results. I propose a new configuration for the comparison functions when floats are involved, call it "Compare Floats" or otherwise. When selected, I suggest that Equals? becomes "Almost Equal?" and the icon changes to the approximately equal sign. EqualToZero could be AlmostEqualToZero, again with appropriate icon changes. GreaterThanorAlmostEqual, etc.
I do not think these need to be new functions on the palette, just a configuration option (Comparison Mode). They should expose a couple of terminals for options so we can control what close means (# of sig figs, # digits, absolute difference, etc.) with reasonable defaults so most cases we do not have to worry about it. We get all of the ease and polymorphism that comes with the built-in functions.
There are many ways to do this, I won't be so bold as to specify which way to go. I am confident that any reasonable method would be a vast improvement over the current method which is hope that you are never bitten by Equals?.
It's got to be a duplicate, but I could not find it...
A significant number of vi.lib VIs are still outputing error codes (I32) instead of an error cluster.
For instance, the famous Ramp.vi:
returns an error -20006 if you ask for zero samples. Type in this value in the "Explain Error..." window of the Help menu and you get:
So it's not that the error code is mysterious and cannot be interpreted (I must say I was a bit puzzled by this discussion on error codes).
NI has to fight with this problem themselves. For instance, here is the code you find in the NI_AALPro.lvlib:AAL Resample Filter Prototype Design.vi:
What is that "?!+Magnifier" VI , you'll ask (AAL Error Information.vi, in the same library mentioned above)? I am probably supposed not to post it, but I will nonetheless, considering what it REALLY does:
Yep, it simply returns the same numeric error code value (again) and the call chain for the VI generating the error (but it won't tell you that the real source is the DLL called in the "Kaiser" VI above). I assume (but I can't prove) that the codes returned by the analysis library are among those recognized by the Explain Error VI.
It is not only an annoyance to not be able simply connect VIs using an error cluster wire, it does not make error handling particularly easy (basically, the way I read the answers of Aristos Queue and Norbert_B in the thread I quoted above is: "reverse engineer our VIs if you really want to 1) get the complete list of error codes it can output, 2) understand their cause").
My suggestion: Hire a couple of interns to sift through NI's VI librairies and change error code outputs into error cluster outputs with proper messages.
Obviously, for compatibility reasons, open previous code with an added unbundle primitive which will return the old error code (with a list of warning after the first compilation). You've done that before and we have survived.
Show where a LV error like "There is not enough memory to perform this operation" is coming from, either in the text of the error dialog (call chain and which node) or in log file, and (if using LV development not runtime) open & highlight the problem location. This is an example of an error that can't be caught by our LV code and doesn't crash LV to produce a crash log.
I often have a situation where certain code parts don't really need to be recalcuated, because their inputs have not changed from an earlier encounter.
For example if a function is the sum of two different complicated and slow calculations where each of the two depend on a different subset of parameters, often only one needs to be recalculated, while the other intermediary result could be grabbed from a cached value. (This occurs for example during the calcuation of partial derivatives).
In some cases, the compiler could probably recognize these situations, but I think we should have a special structure to allow caching of intermediary results.
I typically use a case structure and two feedback nodes as shown in the example on the left. If the value is different, the code in the TRUE case is executed, else the value stored in the SR is returned immediately. (If the code depends on several values, I bundle them all before the comparison operation)
I propose an simple Caching Structure as show on the right that retains that same functionality with less baggage.
Details: The containing code is calculated at first run and stored in the output tunnel. In later calls, it is either (A) recalculated, or (B) the previously stored value returned at the output tunnels. Recalculation only occurs under some conditions (.i.e. usually when actually needed)
The structure has the following features:
There can be an unlimited number of input and output tunnels of any type described above. A recalculation of the inner code occurs if any of the triggering tunnels have a changed value.
We can think of it similar to "short-term folding".
This is a follow through for Zekasa's Idea posted here. It was suggested that the function be a separate one, which I agree. I would like to see this in LabVIEW's basic package, without adding things onto the install, or coding it.
It is many times easiest to work with data in the form of an array. Also helpful in many situations to use arrays inside of clusters. This is a problem when working with functions that require a data type to be a fixed size since they don't accept the combination. I'm asking for full support for fixed-size arrays in Labview and LabviewRT.
See example problems attached. Also open to other ideas as long as they are similarly elegant and easy to use. Also please correct me if I haven't shown the simplest workarounds, etc.
(also possible this is a bug but seems to be a missing feature)