Jump to content
Gan Uesli Starling

How to change content type of N-element cluster

Recommended Posts

My Problem:

I start with an array of N strings. Using the function "Array to Cluster" I get a cluster of 1-element arrays (each containing one string) when what I want is a cluster of N strings.

My Question: How can I do any one of the following:

A. Produce a cluster of strings from an array of strings?

B. Break an array of arbitrary length into N strings?

C. Build a cluster, adding strings one at a time (like pushing onto an array)?

Why do I need this? Am saving widget values to a file at end of probram. Then on a cold restart, the user can elect to re-populate those same widgets with the end conditions of the last test. I had been doing it for up to four sets of each kind of widget using case statements. With four of each kind of widget I got by since each was only 16 cases. But now I must increase some of those four to eight (256 cases). And now they are asking for 12 (number of cases = Way Too Many) and can even see them one day asking for 16 or more (number of cases = OMFG!).

Best solution woud be something like UNBUNDLE but for an array instead of a cluster.

Edited by Gan Uesli Starling

Share this post


Link to post
Share on other sites

My Question: How can I do any one of the following:

A. Produce a cluster of strings from an array of strings?

There is an Array to Cluster in the Cluster palette. You must specify the size of the cluster to make (the default is 9), right click the primitive and select Cluster Size. This is not changeable at runtime as far as I know.

Share this post


Link to post
Share on other sites

Paradon, but you clearly did NOT read my question. Setting cluster size is NOT a problem. I already do that. But from an ARRAY_OF_STRINGS it gives me a CLUSTER of 1-STRING_ARRAYS. And that will not do. I need a CLUSTER_OF_STRINGS from an ARRAY_OF_STRINGS.

Share this post


Link to post
Share on other sites

Sure:

post-13461-0-20716100-1321891055_thumb.p

Doing A with N strings or doing C isn't really possible because clusters have to be defined at development time, and N is a variable that's (apparently) not known then.. I don't know if I really grasp what you're actually trying to do, so posting some code would probably be a good idea.

  • Like 2

Share this post


Link to post
Share on other sites
I start with an array of N strings. Using the function "Array to Cluster" I get a cluster of 1-element arrays (each containing one string) when what I want is a cluster of N strings.
There is an Array to Cluster in the Cluster palette. You must specify the size of the cluster to make (the default is 9), right click the primitive and select Cluster Size. This is not changeable at runtime as far as I know.
Paradon, but you clearly did NOT read my question. Setting cluster size is NOT a problem. I already do that. But from an ARRAY_OF_STRINGS it gives me a CLUSTER of 1-STRING_ARRAYS. And that will not do. I need a CLUSTER_OF_STRINGS from an ARRAY_OF_STRINGS.

Before you get too snippy, I think the reason hoovahh replied the way he did is because your original post doesn't make sense: if you use the "Array to Cluster" with a 1D array of strings then the output is a cluster of strings, not a cluster of 1D arrays of strings with one element each like you suggest.

Drag this snippet onto an empty LabVIEW block diagram and you'll see that it works as expected:

post-181-0-95296300-1321892123.png

My guess is that you're either not using "Array to Cluster" correclty (although I can't imagine how you can use it incorrectly), or your input isn't a 1D array of strings, as you've suggested. Post a code snippet of your issue and we'll try to help.

Share this post


Link to post
Share on other sites

As pointed out by Asbo, for an arbitrary length string array, you can't make it into a fixed-sized cluster.However, you could use variants to build a "Variant Cluster".

If so, OpenG is your friend here. Furthermore, this works with any array type (see attached VI).

2011-11-21_1127.png

ArbitraryArrayToCluster.vi

(OpenG VIs needed -> VIPM)

Share this post


Link to post
Share on other sites

Thank you all for those. I'll be looking into them. Meanwhile, please help me to understand my problem because it still perplexes me. Here is a screenshot of three windows overlaying eachother. At bottom, showing through, is a tiny part of the main VI. You can see where I've put two probes, before and after my problematic cluster_to_array VI. At bottom is the probe results, showing (to my interpretation) a simple array of strings as input and the anomalous cluster of single-string arrays as output. At right is a window showing the contents of my custom VI from which the array-of-strings derives. What is going on here, please?

fusterclucked.png

Here is the result I get using one of the examples offered me. I am running LabVIEW 2010 as 32 bit on a 64 Bit DELL Precision T7500 under Windows 7. Where did I go wrong above?

fusterclucked_2.png

Edited by Gan Uesli Starling

Share this post


Link to post
Share on other sites

You should use the Index Array node:

post-13461-0-81538500-1321902149.png

If you're looking to reduce the diagram footprint of this section of the code, use a for loop and an un-bound property node. Let the For loop index an array of all the control/indicator references as well as the array of values:

post-13461-0-22818900-1321902686.png

Turns out you can't make a snippet use linked references, even if you include the terminal. :( Right-click each of the terminals in the snippet and create a reference. Replace each of the reference controls with the reference constant.

Share this post


Link to post
Share on other sites

[...]

Turns out you can't make a snippet use linked references, even if you include the terminal. :(

It turns out YOU can't do that, but if you use the Code Capture Tool you could. :yes:

post-7534-0-35976700-1321903711.png

Share this post


Link to post
Share on other sites

You should use the Index Array node:

Thank you, that works. Strangely, it is exactly what I was wanting to do in the first place, had I known (or remembered) that the INDEX ARRAY widget could be pulled down for multiple lines out (versus indexing one at a time inside a loop). For the cluster function, that much is obvious in the visual icon, and was the only reason I was going with clusters for this particular sub VI.

Problem is I am allowed to do LabVIEW only seldom (even though I'm the designated 'guru' [coughs embarassedly] for all things LabVIEW) and usually only with other engineers waiting anxiously for me to update whatever it is that needs addressing.

Thanks to everyone who replied.

  • Like 1

Share this post


Link to post
Share on other sites

It turns out YOU can't do that, but if you use the Code Capture Tool you could. :yes:

Shameless! :P I'll consider it ...

But wait! The CCT dropped a wire... Bug?

Share this post


Link to post
Share on other sites
Thank you all for those. I'll be looking into them. Meanwhile, please help me to understand my problem because it still perplexes me. Here is a screenshot of three windows overlaying eachother. At bottom, showing through, is a tiny part of the main VI. You can see where I've put two probes, before and after my problematic cluster_to_array VI. At bottom is the probe results, showing (to my interpretation) a simple array of strings as input and the anomalous cluster of single-string arrays as output. At right is a window showing the contents of my custom VI from which the array-of-strings derives. What is going on here, please?

So that you don't get confused the next time you use "Array to Cluster" and attempt to probe its output, the issue you were having earlier was just due to the way LabVIEW names the output of "Array to Cluster".

LabVIEW takes the name of the input wire and appends [0], [1], [2], etc to it to name each item in the cluster. It also gives the cluster itself that name. Therefore, in your first probe window:

Array (1-D Array of Strings) -------Array to Cluster--------> Array (Cluster of: Array[0] (String), Array[1] (String), Array[2] (String), Array[3] (String) ...)

And in your second probe window:

"" (1-D Array of Strings) ----------Array to Cluster-----------> "" (Cluster of: ""[0] (String), ""[1] (String), ""[2] (String), ""[3] (String)) where "" is a placeholder for an empty string (the default name of a constant).

Share this post


Link to post
Share on other sites

At bottom is the probe results, showing (to my interpretation) a simple array of strings as input and the anomalous cluster of single-string arrays as output.

It is a cluster of strings, not of string arrays. The names of the cluster elements are derived from the indices of the input array - "[0]" is the name of the first string array element. With context help open, hover the wiring tool over the output of Array To Cluster to see its type.

Share this post


Link to post
Share on other sites

[...]

But wait! The CCT dropped a wire... Bug?

I seem to have lost that wire when I edited your snippet. My BD is missing it, too.

Share this post


Link to post
Share on other sites

Thank you, that works. Strangely, it is exactly what I was wanting to do in the first place, had I known (or remembered) that the INDEX ARRAY widget could be pulled down for multiple lines out (versus indexing one at a time inside a loop). For the cluster function, that much is obvious in the visual icon, and was the only reason I was going with clusters for this particular sub VI.

I've worked with people that had years of experience and never knew that. Don't feel bad that you couldn't remember something that a considerable number of people don't know. :thumbup1:

Share this post


Link to post
Share on other sites

Turns out you can't make a snippet use linked references, even if you include the terminal. :( Right-click each of the terminals in the snippet and create a reference. Replace each of the reference controls with the reference constant.

It turns out YOU can't do that, but if you use the Code Capture Tool you could. :yes:

I reported this bug to NI - they're already aware of it, but for reference it's filed under CAR 183817:

This is known behavior that has been reported to our R&D department as a Corrective Action Request (CAR 183817). This behavior occurs whether the element is a Linked Terminal Constant, VI Server Reference, or any other reference constant on the block diagram. This occurs because the default data for a reference constant/control is an empty reference. This works the same way as if you were to create a SubVI and look at its block diagram. Therefore, this is more of a usability CAR rather than incorrect behavior. Obviously, the work around is to simply recreate the references in your application.

Share this post


Link to post
Share on other sites

Thank you, that works. Strangely, it is exactly what I was wanting to do in the first place, had I known (or remembered) that the INDEX ARRAY widget could be pulled down for multiple lines out (versus indexing one at a time inside a loop). For the cluster function, that much is obvious in the visual icon, and was the only reason I was going with clusters for this particular sub VI.

Problem is I am allowed to do LabVIEW only seldom (even though I'm the designated 'guru' [coughs embarassedly] for all things LabVIEW) and usually only with other engineers waiting anxiously for me to update whatever it is that needs addressing.

Thanks to everyone who replied.

Been there, done that, got the teeshirt to prove it!

I am the only LV guru in my company too :)

Share this post


Link to post
Share on other sites

I don't have 2019 at the moment so I can't open yours.  But is this related to the array of variant to cluster stuff?  I made an XNode here that does this.  The reverse is just a single variant to data with the data being a 1D array of variant.

Share this post


Link to post
Share on other sites

I think i knew about that one. Its quite effective, I just have a natural avoidance of using them in anything production related due to the (not supported stigma). The also use quite a few files, I wish LabVIEW could used fewer files. But mostly I wanted to take a renewed crack at this problem. I used @drjdpowell's solution so I wasn't doing anything unsupported (it should be available to anyone using 2019). (because of the type specialization)

Custer To Array: (pass the type directly if possible) otherwise make them a array of variants.

image.png.a3723cefa638e810f1d76dfad042d037.png

Array To Cluster: Get the cluster type and convert it to the proper cluster type.

image.png.8aa47f0c521af9546d2b83b3e7e795dc.png

Pretty much this for 256 Cases :). And Two special cases.

image.png.3367cce991630ac20ec422ac47537b7f.png

image.png.ec5ccbec31c4c2a13d1a465bf9f42cab.png

I Suppose i want the Array to cluster and cluster to arrays to behave more like these by default. (its essentially a behavioral extension of the standard functions)

Edited by Taylorh140
Added reason for 2019 support.

Share this post


Link to post
Share on other sites

Yup, looks like what I expected.  I assume you mean avoiding non-NI XNodes in your code, because there are several people use all the time.  That's fair and when all things are equal I do prefer a VIM over an under(un)supported technology.  I do also agree that the number of files are large even for something simple.  Anyway thanks for sharing.

Share this post


Link to post
Share on other sites

How about this for "Array to Cluster"? It works for any array size. I have not tested whether it is faster or slower than the "array to fixed-size cluster" method, but it is cleaner than having 256 cases to handle all possible clustersaurus configurations.
The "TD_Create Cluster" type descriptor method is a gem you can find at <vi.lib>\Utility\GetType.llb\TD_Create Cluster.vi

image.png.85a1eb7e1d46910db9201beb0b8873d8.png

// Note: you can ignore the error on the unflatten node, an empty array input will return "void" as an output.

Oh, and it's faster than OpenG...

 

Edited by Francois Normandin
  • Like 2

Share this post


Link to post
Share on other sites

I'm not sure what goes on in the subVI, but I'm pretty sure that method is slower than 4 primitives.  That's the major benefit of that method.  Yes there is the draw back of having so many cases, but when they are buried in a subVI never to be seen, and the likelihood of having a cluster with more than 256 top level elements?  I'd personally still prefer the VIM, given the trade off to performance benefit.  But thanks for the alternative.

Share this post


Link to post
Share on other sites

I've considered a similar flatten-unflatten method, in the default case for clusters too large to handle with the other method, but I've never needed clusters that large and the flatten-unflatten method is ballpark an order of magnitude slower, I would guess.

Share this post


Link to post
Share on other sites

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.


  • Similar Content

    • By Fred chen
      Hi
       
      When I call the DLL, there is a structure:
      struct Signal { uint32 nStartBit; uint32 nLen; double nFactor; double nOffset; double nMin; double nMax; double nValue; uint64 nRawValue; bool is_signed; char unit[11]; char strName[66]; char strComment[201]; };  
       
      There is another  Message structure to the above Signal:
       
      struct Message { uint32 nSignalCount; uint32 nID; uint8 nExtend; uint32 nSize; Signal vSignals[513]; char strName[66]; char strComment[201]; }  
        The point is  Signal vSignals[513];
       
      I've tried to solve it like this,but the program will crash.
       
      How to create struct Message ,any good suggestions?  Thanks a lot.
       

      message.vi
    • By Taylorh140
      After working on the set cluster element by name xnode, it made me realize i could use the same concept to convert a variant array to a cluster. The technique is actually pretty simple, the xnode generates a case structure for each element in a cluster in cluster order, wherein a bundle by name is used to set the value and an unbundle by name is used to get the type, a variant to data is used to convert the data. This has some benefits over some methods, you are not limited to 255 elements, although that is not usually the case some of us are paranoid that clusterosaurus giganticous will be larger than expected. It also has a draw back  that is that when converting from a variant array all the elements must have unique, non-blank names, and this is usually the case. 

      I think this technique (though very brute-force) might be useful for some other things let me know what you guys think.

      VariantArrayToCluster.zip
    • By Taylorh140
      This Xnode allows setting a cluster element by label string without using references. I pulled a great deal of inspiration from Hooovahhs Variant Array to cluster xnode, which i suppose this could be used for, another benefit is its not limited to 255 elements. Its mostly experimental because I haven't used it much. 
       
      SetClusterElement.zip

      SetClusterElementLV2013.zip
    • By liskped
      Hi.
      Im working on this prosjekt where I have a TCP communication between two computers (Server & Klient). I have managed to get communication between those two. (Sending and reciving one cluster.) But I want to send and recive more than one. I looked at det Topic "Passing Cluster and Datatype Through TCP" on how to use the OpenG, but I have a problem with "the Variant to Data". 
      What am I doing wrong? Or is there another way to send more data?
       
      The Klient side:


       
       
       
      The Server side: 


       
       
    • By Porter
      Is there any way to automatically wire an index array block to a bundle by name block?

      Auto-wire (pressing space) just adds one wire.
      Note that my cluster contains data of different types so converting the cluster to an array doesn't work.
      If there is a quick-drop shortcut for this I would be very impressed.
×
×
  • Create New...

Important Information

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