08-05-2016 07:39 AM
It sounds like you are using a mega-cluster and passing it in and out of everything.
A careful analysis of the data, grouping only related items togethe,r and encapsulating the various structures in Action Engines and developing proper wrappers for each invoation of the AE will let you share structures between threads.
Are you dismissing the idea prematurely?
Ben
08-05-2016 07:53 AM
I don't think I am. I do have a large cluster sturucture but this is separated into clusters of related data. the problem is that I need to make the program generic and so using just one subVI to update the cluster would be ideal. Using the set/ get enums for each input would just be a mess and I might aswell just use an unbundle and choose which elements I want at each place in my program.
To be honest, when I put up the post I was expecting a pretty simple response where I changed a setting on the subVI (or somehting similar). I didn't expect this not to be a feature. There must be some good reason as to why NI hasn't made one yet as I have looked through similar threads from many years ago with people wanting to do the same thing.
the best solution I found was setting the default to a value that wouldn't occur and then checking for this before either writing a new value or not. This is a good work around but can't be used with booleans and so it isn't suitable for me.
08-05-2016 07:59 AM
Please excuse me as I ask that you please post an image of the code where you have the challenge. I am curious.
Ben
08-05-2016 08:12 AM
Follow to this path for the VI.
Write to Task Info Cluster Folder 5\Surgical Data Analysis\SubVI's/Write to Task Info Cluster.vi
Thanks
Stephen
08-05-2016 08:34 AM
I am sorry but that zip does not give us a glimpse into the context where you are attempting to work with the clusters.
I am going to speculate that your VI passes that cluster from VI to VI alomst as if it is ladder logice turned sideways.
LabVIEW is data driven not operation driven. We develop applications based on what needs to be done with data and not a process as we would find when developing C.
Without going to far out into left field...
This link is a Nugget I wrote on Action Engines that includes a lot of posts by LV experts about the benefits fo AEs. The included examples are very simple but ilustrate that the data is encapuslated and the AE Acts on the data. Note: The data is not pulled out manipulated and replaced. The AE does that work.
This link is a Nugget I wrote about Type Definitions and at the end I illstrate how defualt values for a cluster can be implemented.
While the images in this albumn are not directly applicable to what you are trying to do, it cnotains a collection of image I have shared that include to illustrate hwo a large number of GUI controls (more than 500) can be controlled using what I called a GUI controller.
The main point I think I am trying to offer is "Do the work inside the AE where the data is loacted" not outside the AE.
Just trying to help,
Ben
08-05-2016 08:47 AM
Sorry I thought you wanted to see the VI that I am trying to make. Its not in my actual program at the moment because it doesn't work so i'm just unbundling what I need at each point. I want to replace the unbundling with the generic VI though and just wire what I need instead.
Also you speculate that the cluster is being passed in and out of VIs. This is kind of true but its not a long ladder. The most times it is daisy chained is twice. The main program is event driven state machine and so in different states I will generate a piece of information that i will need to put in the cluster. Hence why I would just like one VI to use instead of repeatedly unbundling the elements that I want to write to.
Thank you for the suggestions though. I will look into these further.
Thanks
Stephen
08-05-2016 09:07 AM
In an attempt to further help you, please take a look at the documents I attached to this thread where we spoke of design.
When we look at each of the states in our applications we can ask ourselves "what do I need to know in this state?" and "What data will the state act on?"
Those questions will tell us that "Cluster A is only used in the first and the second state". for example. When we see a situation where data is only used in a limited set of states the follow-up question "Then why am I passing it through every state?" That obesrvation is solved by moving the data out of the mega-cluster (I am guessing you are using shift registers to preserve the data across states) into an Action Engine that contains the data and is capable performing all of the associated taks that go with that data.
This not only reduces the data copies of large data sets but opens the door to being able to share the enclosed data across multiple threads.
Still just trying to help out!
Ben
08-05-2016 09:21 AM
Sorry, I haven't looked at your code (which, by your own admission, doesn't contain the "use case" you need), but am responding to what seems to be your question. I'm going to make two assumptions -- first, I'm going to assume that the Cluster you are trying to update has been made into a TypeDef (it is so much easier to work with clusters that have been TypeDef'ed), and second that you are using Bundle by Name and Unbundle by Name to access the particular Cluster elements that you need.
Bundle by Name, as the Help indicates, replaces the elements that you wire into it. Implicit in this (and in the fact that the Input terminal is required) is that all other Cluster Elements are simply passed through. In particular, if you use the (constant) TypeDef'd Cluster as the Input Terminal, it will assign all unspecified elements to their default value, which it gets from the Input terminal (holding the TypeDef). On the other hand, if you wire into the Input the current value of the Cluster, it will do what I think it is that you want, namely update/replace only the elements that you specify in the Bundle by Name function.
So without seeing your Use Case, I'm very puzzled why you are having a problem. If you are using Bundle by Name, and if you wire the current value of the Cluster into the Input terminal of this function, it should deliver exactly the function that you seem to want.
Bob Schor
08-05-2016 10:24 AM
@Bob_Schor wrote:Sorry, I haven't looked at your code (which, by your own admission, doesn't contain the "use case" you need), but am responding to what seems to be your question. I'm going to make two assumptions -- first, I'm going to assume that the Cluster you are trying to update has been made into a TypeDef (it is so much easier to work with clusters that have been TypeDef'ed), and second that you are using Bundle by Name and Unbundle by Name to access the particular Cluster elements that you need.
Bundle by Name, as the Help indicates, replaces the elements that you wire into it. Implicit in this (and in the fact that the Input terminal is required) is that all other Cluster Elements are simply passed through. In particular, if you use the (constant) TypeDef'd Cluster as the Input Terminal, it will assign all unspecified elements to their default value, which it gets from the Input terminal (holding the TypeDef). On the other hand, if you wire into the Input the current value of the Cluster, it will do what I think it is that you want, namely update/replace only the elements that you specify in the Bundle by Name function.
So without seeing your Use Case, I'm very puzzled why you are having a problem. If you are using Bundle by Name, and if you wire the current value of the Cluster into the Input terminal of this function, it should deliver exactly the function that you seem to want.
Bob Schor
First off, I don't think I'm explaining myself very well and your assumptions are correct.
The problem is this. I want a subvi to update variables in a cluster. All variables must have a terminal to the VI. However the values to these inputs are generated in different states of my event driven state machine. So ideally I want a subVI that can be called at different places in my code. As the cluster is updates in different places I don't want to wire every terminal as this would make a huge mess of my code. By not wiring the terminal the default is passed and so I end up with values in the being over written with default values.
I want to ignore the default values (that are passed when the terminal is not wired) and keep the current value in those elements. But there is no good way of doing this that I have found. Simply checking for a default value and then ignoring this input is not suitable as I may actually want to pass the default - this is particularly not suitable with booleans, other types could have a default assigned that would never be passed (-ve number for example).
08-05-2016 10:39 AM
LV
is doing what you tell it do in this VI.
You sub-VI is saying "add another elemet to the array of cluster with the values as indicated by the Icon connector.
You options are;
Don't try to use a single sub-VI, use a variety to do different things.
Only change one element at at time with a sub_VI for each.
Switch-over to LVOOP and create accessors so you can pull-down to expose multiple inputs.
Use a Bundle by Name" instead of the sub-VI.
Put the data in an AE and create actions for each flavor of new cluster you want to add.
Ben