LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Different TypeDef Clusters, Same Malleable VI

Solved!
Go to solution

I am working on a series of VIs that all need to perform the same basic actions on a state cluster, namely bundle/unbundle by name. Each VI has a different state cluster, but they contain similarly named elements. i.e. each cluster will have the following named elements: DAQ Tasks, ShotNumber, Data, Config, where Data is a different datatype for each VI. For this VI let's say I want to unbundle ShotNumber, and rebundle it with a new value, but since Data is a different shape/type for each VI I can't just use a single subVI for this. My thought was to use a malleable VI with a Type Specialization Structure, but I quickly became lost in the weeds on this and it felt like I was over complicating it. Should I just have the cluster input be a variant, and then convert the variant to the correct type def based on some other logic? Or is there a better way to do this?

 

nwford_he_0-1753123570123.png

 

0 Kudos
Message 1 of 9
(302 Views)

Hi,

 

Your approach seems correct to me.

 

I would just remove the Type Specialization Structure, to allow any cluster containing the appropriate named elements (the caller will be broken in case an incompatible data type is wired to the malleable VI).

 

Also, I would change the "Label" input data type to a type-defined enum rather than a string, since the bundled cluster elements are known at compile-time.

 

Finally, I would remove the "Actions" output, as it seems redundant with the "Label" input.

 

Regards,

Raphaël.

0 Kudos
Message 2 of 9
(280 Views)

If you delete the type specialization structure what should the input/output cluster be wired as on the front panel? Just an empty cluster? A cluster with the shared named elements I am going to unbundle? 

0 Kudos
Message 3 of 9
(267 Views)
Solution
Accepted by nwford_he

I can think of two relevant options:

  1. The direct answer to the question would be that you can use the OpenG LabVIEW Data VIs to manipulate clusters as variants, so you can just set the value by name (if it actually exists in the cluster. You'll have to account for error handling).

    Alternatively, if you don't want to install all of that, you should be able to use Variant to Data to convert a cluster to an array of variants and then iterate over them and use the Get Type Information VI from the Variant\Data Type Parsing palette to find the relevant element and replace its value and then convert back, although I haven't tested that thoroughly. I haven't looked into this recently, but there doesn't seem to be an easy way to get back from the array of variants to a cluster with this method. It looks like you can use Array to Cluster, but that requires you to statically define the number of elements in the output cluster, and there you could probably use the structure to have multiple frames, but it doesn't feel clean.
  2. Another option is moving from clusters to classes and use inheritance to separate the relevant element to its own class, so that it is the only one which is responsible for it. I don't know if this option is relevant, as that depends on your exact use case. It's certainly a bigger change.

___________________
Try to take over the world!
Message 4 of 9
(244 Views)

Ooooh good call on that OpenG library. I use a lot of their cluster manipulation functions already (that same VI even) I didn’t think of just giving the polymorphic terminal a variant actually. I’ll test that out tomorrow, but I don’t see any reason why that wouldn’t work. 

0 Kudos
Message 5 of 9
(240 Views)

@nwford_he wrote:

I am working on a series of VIs that all need to perform the same basic actions on a state cluster, namely bundle/unbundle by name. Each VI has a different state cluster, but they contain similarly named elements. i.e. each cluster will have the following named elements: DAQ Tasks, ShotNumber, Data, Config, where Data is a different datatype for each VI. For this VI let's say I want to unbundle ShotNumber, and rebundle it with a new value, but since Data is a different shape/type for each VI I can't just use a single subVI for this. My thought was to use a malleable VI with a Type Specialization Structure, but I quickly became lost in the weeds on this and it felt like I was over complicating it. Should I just have the cluster input be a variant, and then convert the variant to the correct type def based on some other logic? Or is there a better way to do this?


If there is a limited number of possible cluster types, you would create a type specialization case for each and unbundle/process the relevant cluster element right inside the type specialization. Now the cluster names don't even need to exactly match as long as you know what they are for each typedef.

 

We probably can give more specific advice once we know the operations that need to be supported and other details.

0 Kudos
Message 6 of 9
(210 Views)

OpenG worked! No malleable VI even needed. And since I already have the typedef I am sending as a message in there, I can always make sure that my names are synced up using the Get Data Name VI in the same library (it's almost like it was made for this since the output terminals of one line up perfectly with the input terminals of the other.) Thanks. 

 

Updated code for anyone that stumbles upon this in the future. 

nwford_he_0-1753206072358.png

 

0 Kudos
Message 7 of 9
(187 Views)

Just bear in mind, nothing will beat a VIM with type specifiers for performance, but if that's not an issue, the OpenG solution should be fine.

Message 8 of 9
(181 Views)

@nwford_he wrote:

OpenG worked! No malleable VI even needed. And since I already have the typedef I am sending as a message in there, I can always make sure that my names are synced up using the Get Data Name VI in the same library (it's almost like it was made for this since the output terminals of one line up perfectly with the input terminals of the other.) Thanks. 

 

Updated code for anyone that stumbles upon this in the future. 

nwford_he_0-1753206072358.png

 


This seems a bit convoluted / impractical to me:

 - When using your VI, the RT state cluster must be converted to and from a variant.

 - It does not allow flexible data types for your common named cluster elements.

 - The use of the string data type for "label" opens a possibility for typos in the element names, while it seems they are known at compile-time.

 - The name obtained with "Get Data Name.vi" will simply give the cluster constant's name, which is independent from the type definition.

 

I see 2 methods (here for your example of writing a cluster element as a JSON string):

 

1. More efficient: Using a VIM (Malleable VI) and in place bundles / unbundles:

raphschru_0-1753825011156.png

The VIM will adapt to any cluster that has at least the common named elements, with the correct data types (depending on restrictions).

 

2. More generic: Using a VIM (Malleable VI) and OpenG cluster functions:

raphschru_4-1753826554577.png

Here it does not need specific implementation for each specific named element, but is less efficient because of the decomposition / recomposition of the cluster by the OpenG functions.

 

Attached is a benchmark to compare both methods.

 

Regards,

Raphaël.

0 Kudos
Message 9 of 9
(76 Views)