From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Wrong linking of cluster elements after deleting elements from typeDef

Hi everyone,

 

This is an issue that came up in a couple of previous posts, such as:

typedefs update incorrectly

Deleting Control from Type Definition casuses many misreferences and program errors in Block Diagram

Unbundle By Name Changes Selected Field

 

It also resulted in a couple of CARs.

However it is still not acceptably solved or I haven't found a satisfying solution so far...

 

we are using LV2014 SP1 (professional development system), Windows 7

 

Problem Description:

 

  • In our (OOP) LV Project we have a large (strict) typedefinition (with sub-typedefs) which is in an object (don't know if that's relevant).
  • If we make certain changes to this typedef LV sometimes relinks  variables wrong in an unbundle/bundle by name. 
  • This especially seems to be the case when certain variables have the same name but are in different sub-clusters
  • I attached a minimum example project to this post and screenshots of what i mean.

To reproduce the problem:
1. Open VI (test_MinimalBsp_WrongUpdateLinkingOfUnbundleByNameTypedef.vi) and note unbundle by name: correct values are wired to indicators (pic before), close VI

MinimalBsp_wrongClusterLinking_before_5.PNG

MinimalBsp_wrongClusterLinking_strictTypeDef.PNG

2. open strict TypeDef (supercluster) and delete e.g. subcluster 3 and subcluster 4, save and close
3. open VI again. Note that it is in "unsaved changes" state (asterix next to VI name) but no broken arrow, open BD and notice that subcluster 3 has been exchanged with subcluster 2, and subcluster 4 with subcluster 1.

MinimalBsp_wrongClusterLinking_afterDeletion_5_firstdeletion.PNG

4. close the VI (don't save) and open strict TypeDef (supercluster) and delete more e.g. subcluster 1 , save and close

5. open the VI again and notice that now all elements previously referenced to the subcluster 1 are now referenced directly to the elements in the the SuperCluster: so wrong linking can happen over different levels of clusters.

MinimalBsp_wrongClusterLinking_afterDeletion_5_seconddeletion.PNG
additional:
6. if you close the VI without saving and reinsert the subclusters in the strict typeDef and save it. then open the VI,  the linking is correct again.

 

 

 

The solution I got from NI so far was to rename the variables to different names. I think that my question and therefore the nature of the problem was not understood properly by the AE.

But anyway, this solution is unacceptable as we have for example a cluster with many identical elements of a sub-typedefinition i.e.

Cluster

-subcluster1 (sub-typedefinition)

-subcluster2 (sub-typedefinition)

-subcluster3 (sub-typedefinition)

...

and renaming all the elements in this sub-typedefinition for each subcluster would go against the very idea of a typedefinition.

 

The biggest issue here is that we might not even detect that LV linked something wrong, because the VI is not broken if the datatype of the old and the new element that is selected in the (un)bundle by name is the same.

This is very hard to debug as we don't see any error in the first place. Therefore the problem could only turn up when the application is already in use by our customer.

Furthermore, as we don't know when this happens we cannot be sure that our application will work as expected after each modification of the typedef.

 

Possible workarounds (summary of previous posts):

 

  • "If you are going to delete, then first edit the type def to change the data type of what you are about to delete, to an incompatable data type to break your code ON PURPOSE. Then go through the code an remove all rfs to that element BEFORE you delte it."

We already use this as "good practise", however we had the issue also when we did not delete an element. LV wrongly relinked two elements with the same name but on different levels in the cluster. It is hard to tell what we did as the error came up months later but I guess we changed some other part in the main typedefinition causing LV to relink all (un)bundle by names.

 

  • One other way to avoid the problem is to always work with the cluster and get the array of references to all the controls in the cluster.  Then use that to search for your control of interest by name.  Then once you find that you can cast to a more specific class on that reference and pass that to a property node explicity and work with the property you want.

     

    The two main disadvantages,

    1.  A lot more code you need to write.

    2.  It still has the flaw that if you change the name of the control in the cluster, you'll have to go around and change the string constant you used to search for that specific name.

     

    Advantages,

    1.  I won't break the other property nodes.

    2.  If you do forget to change the string constant, you should be able to catch the error at run-time.

As our application is rather large, exchanging all access of this cluster elements with this method is an immense work, not to mention that it would make the code very unreadable.

 

So my questions are:

  • Can anyone tell me when this mixed-up linking can happen? e.g. when to be careful with it?
  • And why is it happening? Or how could we avoid it?

Ben has asked this before:

  • how does linking of elements in clusters work under the hood in LV? It seems to me that it checks for the name somehow (although this was denyed in one of the above points).

Any suggestions and helpful comments are appreciated.

 

Best,

Raeff

 

 

 

 

 

 

 

Working with LV2011, LV2018 and LV2020
Message 1 of 19
(4,038 Views)

With Enum typedefs i use strict typedefs only, exacly for this reason.

Don't know wether this applies to other typedefs, too.

 

0 Kudos
Message 2 of 19
(3,986 Views)

We are actually using strict typedefs. I mentioned it in one of the first lines and left it out later in the post for simplicity.

Also I don't think that it is a problem of strict typedef or typedefs but rather how the bundle by name relinks it's element when the cluster is changed...

Working with LV2011, LV2018 and LV2020
0 Kudos
Message 3 of 19
(3,975 Views)

Hi Raeff,

 

short answer to your lengthy post:

When you change the datatype of your wires you need to check all instances of this datatype in your code!

 

LabVIEW tries to be smart with changes to (typedef'd) clusters, but when you start to reorder elements it easily gets "out of sync". It's your task as programmer to keep track of such traces…

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 4 of 19
(3,972 Views)

Hi GerdW,

 

Thank you for your reply.

 

 

So how should I check all instances of this datatype? Could you elaborate a bit more?

 

Best,

Raeff

Working with LV2011, LV2018 and LV2020
0 Kudos
Message 5 of 19
(3,961 Views)

Right-click the typdef and search for all instances…

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 6 of 19
(3,958 Views)

 

Yes that would work for part of it.

However, I would need to check every parent VI of a subVI which has this data type as an output. E.g. a subVI outputs my changed typedef and I use an unbundle in the parent VI.

That is a lot of work for any small change on the typedef.

 

I partially agree that I as a developer need "keep track of such traces…" because as you said, LV gets easily confused, and I need to check for every possible confusion that LV did after my changes?

Seems to me that LV creating a lot of work to do for me.

 

I still don't understand why the bundle by name would relink an element rather than just say "my reference is gone, therefore my link is broken"...

 

Maybe it would help if I can better understand how LV relinks when I reorder elements. Do you know more about this? Does it search for the name in this cluster level and then a level higher up in the cluster.

Or does it pick the elements according to the order in the cluster (this should be the case with the "bundle" right?), but then reordering of the cluster should not cause LV any problems.

 

So did I understand you write that you are saying that every time we make a change on the typedef we have to check our whole code?

Or only when we reorder the elements? deleting also goes under reordering, but adding an element would add it at the end of the cluster, therefore no reordering of the other elements

Working with LV2011, LV2018 and LV2020
0 Kudos
Message 7 of 19
(3,933 Views)

Hi Raeff,

 

However, I would need to check every parent VI of a subVI

You should open the main VI, then open the hierarchy, then right-click the typedef in there to search for instances.

Or open your main VI and the typedef, then search instances from right-clicking the typedef icon…

 

Seems to me that LV creating a lot of work to do for me.

No. You created that work!

 

- It's you that starts to change a typedef.

- It's you that didn't designed it's code and data structures before starting to code!

- It's you that designed code with so many dependencies: you might think about (better) encapsulation of your data to avoid massive Unbundle(ByName) usage in a lot of VIs! (Use AEs/FGVs or OOP to encapsulate your data!)

 

So did I understand you write that you are saying that every time we make a change on the typedef we have to check our whole code?

In general: yes! When you change data structures you need to check all code handling those data structures!

 

Or only when we reorder the elements? deleting also goes under reordering, but adding an element would add it at the end of the cluster, therefore no reordering of the other elements

- Reordering clusters: check all instances of the cluster typedef.

- adding elements (at the end) to the cluster: usually no harm. But again: with changing data structures you need to check all code handling those data structures!

 

You are the programmer, you are responsible for your code!

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 8 of 19
(3,922 Views)

The biggest problem you have here is that you created a mega cluster that combines apparently unrelated data from all over the place. Considering that you say to use LVOOP that seems a bit strange. OOP is meant to help with proper encapsulation of data and methods so that only small components need to know about a particular datatype, not the entire application.

 

As to the problem at hand this has been a reoccuring issue and NI has worked many times on it to make it smarter with partial success only to make it appear again in different ways. It seems one of the areas in LabVIEW where whatever strategy they choose somewhere somehow something goes wrong for some people. Generally LabVIEW used to only care about element index, then learned to reapply the bundle and unbundle based on name. However I'm not sure about how the strict typedef influences this. I used to use strict typedefs all over the place in my early LabVIEW development but moved away to use normal typedefs instead for a long time now. One reason was that strict typedefs did cause more trouble like what you see when a modification to the typedef happened. I was under the impression that this has been sort of remedied since but it seems there is still something going on.

 

Also strict typedefs are in many cases to strict as I only really care about the datatype to be consistent and not so much about if the control looks exactly the same everywhere. Last but not least there were certain issues in the past when building applications that contained strict typedefs.

 

I think changing the strict typedef to be a normal typedef and restructering your mega cluster to have a much smaller scope and siize should help even more also in terms of maintainability for later on. Application wide mega clusters are about as bad as globals spread everywhere through your code.

Rolf Kalbermatter
My Blog
0 Kudos
Message 9 of 19
(3,909 Views)

Hi GerdW,

 

I did followed your suggestions:

You should open the main VI, then open the hierarchy, then right-click the typedef in there to search for instances.

Or open your main VI and the typedef, then search instances from right-clicking the typedef icon…

Both the methods returned the same search result as i had before. There are 20 VIs listed, but there are many more parent VIs, which I need to check for manually.

 

- It's you that starts to change a typedef.

Isn't that the idea of a typedef, that I have one master that I change and all instances update with it. Or is changing a typedef "bad practise"?

- It's you that didn't designed it's code and data structures before starting to code!

I agree (I was not the person who designed it tough). However, each software that you develop over years will need some modifications when you make new versions and include new features. 

- It's you that designed code with so many dependencies: you might think about (better) encapsulation of your data to avoid massive Unbundle(ByName) usage in a lot of VIs! (Use AEs/FGVs or OOP to encapsulate your data!)

That is a very valid point. I'm sure there are better ways of doing the encapsulation and I like to hear more advice on how to encapsule.

So generally I got that using too much unbandle by name is bad habit. We haven't been using many FGVs but I'll make sure to mention it in the next meeting.

What are AEs (appart from Application Engineers)?

We are using OOP and yes probably not in the most effective way in some cases. you suggest using more (child classes) to handle encapsulation more effectively?

 

hi Rolf,

Thanks for your input as well.

I will try using typedefs rather than strict type defs. In some cases keeping the exact format of the typedef  is desired, therefore we use strict typedefs there.

 

Right, having such a mega cluster is surely not the best way to deal with the data and we need to rethink on this.

This mega cluster actually consists of subtypedefs. E.g. We have a mega cluster systemConfiguration which consists of multiple subclusters e.g. Calibration, Scan, HWconfigs, Visualization and so on.

Should we make a child classes for all of these subclusters?

 

Is it correct that typedefs should generally not be part of a class? i.e. rather use the classes private data if you want this data to be part of the class?

 

Guess my general question is, what is good practise with encapsulating data using LVOOP?

happy for any advice.

 

best,

Raeff

Working with LV2011, LV2018 and LV2020
0 Kudos
Message 10 of 19
(3,876 Views)