Jump to content

Aristos Queue

Members
  • Posts

    3,183
  • Joined

  • Last visited

  • Days Won

    202

Posts posted by Aristos Queue

  1. AQ's general thoughts on project, library and VI relationships:

    1. A VI is a function dedicated to a specific task. It has no particular allegiance to any particular application. It doesn't care who calls it... it does what it does when it is invoked.
    2. A Library is a collection of related VIs. Some libraries are dedicated to a particular task: .lvclass libraries are dedicated to defining a new data type. .xctl libraries are dedicated to defining a new control. Libraries are coherent distribution units -- all the VIs therein should distribute together. The VIs that test a library's functionality should not be in the library since you don't generally want to distribute your test harness. Again, libraries have no allegiance to any particular application in LV.
    3. A project *is* a particular LV application. There is a one-to-one correspondence between "something I as a user generate to be an end product" and a single .lvproj file. There is some leniency to this one-to-one relationship if a single chunk of VIs are used to build multiple build targets -- perhaps both an exe and a dll, or multiple flavors of source distribution, for example -- but these are just flavors of the same general deliverable.
    4. The project should include the test harness for the deliverable.
    5. A VI and a library are reusable components. They may be used by multiple projects. If you intend to have a component that you share between multiple projects, then there should be a project for that shared component itself. That project should contain the test harness for that component. The other projects that just use the shared component don't include the test harness for the shared component.
    6. In the most extreme of stringent coding practices, the project for the shared component has a Source Distribution build. It is used to generate a separate copy of the source code which will be used by all the other projects. The other projects do not ever reference the original source code of the shared component. This protects against unintended edits, and allows you to always regenerate from the shared component's project a clean version of the shared component.
    7. The post above said "that lvlib is a namespace and has a one-to-one pairing with VIs". The Library actually has a one to many relationship with VIs. Each lib contains multiple VIs. You should package together VIs that are related, to the extent that feels reasonable to you. Some libs are very small. The Analysis library that ships from NI has 600+ VIs in it. In the words of Yoda, "Size matters not." It is a question of how related the functionality is and whether the VIs are intended to be distributed/used together. You can use sublibraries to give further breakdown if that is useful.
    8. Make VIs private or protected whenever possible. It helps your debugging later if you know that no one else could possibly be calling a given VI. And it makes it easier to change conpanes if you know that no one else is using a given conpane.
    9. My personal goal is that all VIs should be owned by either an XControl library or an LVClass library. Plain libraries should only own other libraries for packaging and distribution purposes. This is in accord with the maxim "All bits of data may be thought of as part of some object; all functions may be thought of as actions taken by some object." Do I actually keep to this goal? No. LabVOOP still has inefficiencies in some places, and sometimes I get lazy. But I'm working toward that goal and do believe it is viable.
    10. All the VIs for a single project go in a single directory unless they are components intended to be shared among many projects. Within that single directory, I recommend creating subdirectories for each library. I do not recommend that you have any further disk hierarchy. If you create folders within your libraries, so be it, but don't make directories on disk that reflect those folders. Why? Because folders are the organization of your library for presentation as a palette and for providing scope for VIs. It is really annoying to want to change the scope of a VI and have to save it to a new location to keep your disk organization consistent. And it serves no purpose. If the library is a coherent distribution unit, then when you're on disk you're supposed to be moving the entire library as a chunk. Some people complain that that makes it hard to use the "Select a VI..." item in the palette. But I suggest that is what drag-n-drop from the project is for. Use the project window as a pinned palette during development. When you deploy, deploy the library with a .mnu file that is part of the regular palette hierarchy.
    11. All of this can feel like overkill for a single developer by him/herself. But I find that these guidelines help avoid cross-linking problems, debug problems and distribution problems even with my own projects that aren't shared with any other G developers.
    12. All of the above are my PERSONAL thoughts and should not be taken as NI speaking. I am NOT a full or even part time G developer. I do C++ and G is my hobby, so take my advice with a grain of salt. But, on the other hand, I do spend a lot of time talking about and thinking about what the right way to do things in G is, and I know how the internals are designed. At any rate, its your call how valuable you think all this advice is.

    PS: If your clusters are already typedefs, put the typedef into the project window, popup on it and choose "Convert Contents of Control to Class." This will help you on your way to converting your project over.

    • Like 1
  2. QUOTE(Daklu @ Aug 17 2007, 02:57 PM)

    I have one variable I need to compare against several other variables in order to choose which case to run. It's easy to do in text languages using ElseIf or Select statements, but I can't figure out if it is possible for Labview case structures to be defined by variables.
    Pseudocode [/u]If A<W then   [u]

    The syntax is in the online help for the case structure. In general, wire the variable to the selection terminal (the '?' terminal) and then put the test in the case selector. For numerics:

    ..1 is anything less than or equal to 1

    3..5 is anything between 3 and 5 inclusively

    4 is just 4

    4.. is anything greater than or equal to 4

    default is anything not covered by any case

    ..1, 3.. is anything less than/equal to 1 or greater than/equal to three.

  3. QUOTE(Ben @ Aug 17 2007, 11:02 AM)

    That reminds me Stephen, is that were you got the "mu" from?

    It is one of two sources. The other is directly from the Zen koans themselves. I found it in the koans but didn't really grasp the concept until Goedel, Escher, Bach.

    Something you should know about GEB... the book has two main divisions. The first half is incredibly good. The first half of the second half is good. After that it bogs down. I was talking to a CS professor of mine. He asked if I had read the book. Chagrined I said that I had gotten through 3/4 of the book, but just couldn't finish that last chunk. The prof said, "That's ok. There's not a faculty member in this department who was able to force themselves through that last chunk. Really, it won all the awards for the first half." So if you similarly grind to a halt, you're in common company. Those few I have met who actually finished it say the trail of the book is a rehash of the first half in case you didn't get it the first time, but with more rushed writing style.

  4. QUOTE(tcplomp @ Aug 11 2007, 01:05 AM)

    Is it only VISA resources or also Daqmx resources?

    They appear to be the same to me, and I don't want to be bitten by it.

    One user reports that it also affects DAQmx, but I have no confirmation of that at this time. It is definitely possible.

    This issue has been reported to R&D (4CG9B3J1) for further investigation.

  5. QUOTE(Tomi Maila @ Aug 17 2007, 02:48 AM)

    One bug I've also encountered but I've not yet reported it to NI as I had not had time to test how to reproduce it. When I changed the name of a class type control in a private data cluster of another class, the name change didn't penetrate to member VIs. All bundle and unbundle nodes still appeared as if the name had not been changed. Compiling the project with ctrl + shift + run didn't help (if I recall correctly). So there seems to be some book keeping issues related to class wire item naming in LV 8.5 but this doesn't affect runtime properties.

    Known issue. If you just change the name of an element, the type isn't updated. You need to make a change that changes the type itself. Workaround: Add an element to your cluster, do File>>Apply Changes, then delete the element. This will get the other elements to update to their new names.

  6. QUOTE(MikaelH @ Aug 16 2007, 10:47 PM)

    I think it is fairly awkward to call that a cast. When I cast from 8bit integer to 16bit integer, I don't create any new information, I just rearrange the info that is there. The same is true with casting a string to an array of bytes. When casting a parent to a child, you really are creating information ex nihilo.

    For LV to offer a primitive that does this sort of casting for an arbitrary class would be a complete violation of encapsulation. Suppose that the parent allows you to set values in the range 1-10. The Child class overrides the SetValue method and constrains the value to be 1-5. A user could construct a parent class with a value of 10 and then force construct that as a child, resulting in an invalid child class.

    Neither C++ nor Java allows you to cast a value of the parent class as a child class. I don't know of any that allow this sort of thing. You can, as I did in my VIs, construct/initialize a child from a parent, if the particular parent/child relationship finds that to be appropriate. But a generic cast of this sort would be a very bad thing for any OO language to support. Languages do exist that allow you to cast a *reference to parent* as a *reference to child*. That's a very very different thing.

    Let me go one step further and say that in the vast majority of cases where you might think you want this ability, you've actually got the wrong relationship between the classes. Instead of inheritance, you should have containment. The "child" class should actually contain as a private data member an instance of "parent" instead of one inheriting from the other. Thus the parent data gets constructed at time N and at time N+1 the child data gets constructed with that parent data as a data member.

  7. ARGH! It's the "VISA" datatype in private data control bug!!!

    Here's what you have to do... go back to the 8.2 version of your class. Load the class into memory. Open the private data control and resize the VISA control. (You can actually make any edit to the private data control; that one happens to be safe to do without changing your data type at all.) Then you can save the class into 8.5 and it will load correctly.

    This is the same bug earlier encountered by another LAVA user.

  8. QUOTE(Tomi Maila @ Aug 16 2007, 02:54 PM)

    My opinion is very close to Aristos Queue's view here. I'd however add a True Color class above the 24-bit image to allow 32-bit images to be added later on. I could also consider creating a single wrapper class for all LabVIEW image types and use this class as a private data member for all the other classes. For example 8-bit image could have a LabVIEW image in it's private data and delegate functionality to LabVIEW image.

    p.s. AQ, do you think it would be possible in a future version of LabVIEW to make it much easier to use composition? I'd like to have an option to create new delegated method so that LabVIEW would automatically generate the method to have the same interface as the same method in a class in private data. So should I have a method jump.vi in a class in my private data, I could make LabVIEW to automatically create a method to my class that would delegate the call directly to jump.vi.

    Tomi

    Yes, that does seem like something useful that NI could do. Having said that...

    The LV features for "Save As on a VI" and "Add VI to library" are already public. The private functions for replacing a control are known by many folks. This is the sort of tool that LV users could write with some ease, I think.

  9. You want a primitive (or property node or other LV node) with different behavior than the current primitive.

    But you have many different configurations that you'd like the new prim to support.

    And you might have other modes that you might want for particular cases, so the uses are a bit open ended.

    And you've already written the VIs that would do exactly what you want.

    But Create SubVI doesn't work because that causes the data types to be fixed.

    May I suggest that what you really want is polymorphic tunnels on subVIs? Enhancing a single prim is fine, but this is exactly the kind of request that makes me want to find a better solution language-wise.

    But I'll pass your suggestion along to the folks that own these primitives.

  10. This is a problem that can affect any library type in LabVIEW, not just .lvclass files.

    At a guess, I'd say that you've got cross-linking problems. Suppose the project stores the paths for VI A and VI B. Well, VI A uses VI B as a subVI, so it stores a path to VI B. If the path that VI A stores for VI B is different from the path that the project stores for VI B, there's a potential cross-link problem.

    With LV 8.5, we massively improved the ability to detect, untangle and avoid cross-linking. The tools work really really great.... for VIs. When libraries get involved (which means .lvlib, .lvclass, .xctl, and .lvsc) the detection works well, but not so much the untangling. Normally a project loads all the libraries listed (not all the VIs in that library necessarily -- it does for some library types, but not others -- but the library file itself is always loaded). When cross-linking is detected, the project tries not to load the libraries so that the user can manually open the libraries from disk (by using File>>Open) to select the ones that he/she really wants the project to use.

    I'll bet that you made a copy of your project to protect your 8.2 source code when you loaded it into 8.5. And I'll bet that one of the VIs (or libraries or the project itself) in the 8.5 source code *somehow* remembers a path over to the 8.2 source code. And that is leading to the cross-link detection. This problem could also be caused if you saved *some* of the VIs in your project but not all of the VIs in your project when you opened in 8.5 -- did you remember to have all the VIs in your project in memory at the same time when you did Save As? If not, some of them may remember the old path.

    Back in 8.2, try building a source distribution of your project to create the copy and then open the new source distribution in 8.5.

    PS: I presume that the team that made everything work so well for VIs in 8.5 will be returning to further work on libraries in a future LV version, but I have no information about this.

  11. General rule: If you have an enum or ordinal value that is set at the start of the object and is unchanged during the lifetime of the object, that should probably be a child class. I agree that your indexed image sounds best. Based solely on the information presented here it sounds like what you'd want is

    Image

    __|

    __+-- 24-bit image

    __|

    __+-- Indexed image

    ______ |

    ______ +-- 8 bit image

    ______ |

    ______ +-- 4 bit image

    ______ |

    ______ +-- 1 bit image

    Then you can avoid all the duplication of code for the 8, 4 and 1 cases by putting that functionality on the common parent, but you leave yourself room for specific behavior for the 8, 4 and 1 cases if you need it at some point in the future.

    I don't have any info about the future of image handling in LV. That would be a question for another developer.

  12. QUOTE(Jim Kring @ Aug 15 2007, 02:19 PM)

    Any word yet on whether this might be addressed in a future version of LabVIEW? :)

    Several words, including the phrase "darn pushy users." :P

    No, I have no idea if this will be addressed at this time. It'll be any number of months before I get back to low level bug fixes. Right after release is when I generally wander off to the bigger projects. Otherwise I could spend lifetimes just tweaking small things, and let me tell you, that gets boring fast. The mind begins to grasp at any passing fancy that seems more exciting than endless bug fixing, and the programmer, in such deranged state, is driven to such madness as to put just-in-time advice dialogs up after every mouse click. Trust me ... it's better not to go that route.

  13. An effective demo... get a C programmer or Java programmer to write the standard "random number strip chart" VI ... two parallel loops updating two displays. Compare the code between them. Point out to your boss that anything that C/C++/JAVA can do, LabVIEW can do as well since they're all complete programming languages. The advantage is the natural parallelism and the code readability to layity. The very fact that your boss can understand the LabVIEW code and probably not the other may go a long way to convince him that the overhead of bringing a new hire up to speed on a LabVIEW code base is generally less than the overhead of getting them to learn a C/C++ code base. That savings right there may be enough to convince.

  14. QUOTE(Ben @ Aug 14 2007, 03:12 PM)

    Are the days of the QSM behind us?

    I think we'd need some more details about what exactly you think is behind us. NI just released the new Statechart Module for building really advanced state machines. I don't think that architecture is behind us. Are you simply referring to programming individual state machines should be avoided in favor of using some reusable framework? Because that I agree with.

  15. QUOTE(shoneill @ Aug 13 2007, 08:00 AM)

    On a slightly unrelated topic, I wish there was the ability to perform "Dynamic dispatching" based on Data type, or even just on Strict Typedefs.......

    You're talking all data types, not just LV classes, right?

    The problem you're facing (I know because I tried this as one of the initial approaches to classes) is that you need a central data type repository (such as the .ctl) that knows "this VI is my 'add' function and this other VI is my 'subtract' function" etc. The ctl has to store all these relationships to these VIs. The result is something that looks a whole lot like a library, with a centralized data type, which is effectively what a LV class is. The piece that we sidestep is the map from "function XYZ" to "implementation ABC". That would be operator overloading and requires that there be a map of all possible functions to overload in LV to the particular implementor.

    I've played around with such concepts, and they get pretty ugly, both on the debugging side and on the UI side. Personally, I don't particularly like open-ended plugable functions (aka operator overloading). With the dynamic dispatching of classes, I can view the class hierarchy and know whether or not a given class has a given functionality. With arbitrary overloading, I become less sure at every turn whether that "add" primitive that I see on the diagram is actually an add.

    James Gosling, the inventor of JAVA, left operator overloading out of JAVA because he saw C++ and noticed that it was now *ANSI standard* to use the left shift operator for output to a file. I've seen C++ code where "a == b" was overloaded to not actually evaluate whether a equals b but instead was a special type of assignment (deep assignment instead of shallow assignment, for those who know pointers). That sort of horrific situation is not one that I want LV to enter into.

  16. This is not a bug for typedefs. Typedefs are dumb. They have no memory. Other tools that index into typedefs store indicies or store names (which ever seemed most logical for that particular tool), but neither is satisfactory when the typedef gets edited. The typedef does not remember "This was 1, this was 2, and this didn't exist at all before" to allow other tools to correct themselves. The behavior you get is the behavior you get.

    If you want a datatype that does know where its elements go from version to version, that's LabVIEW classes. That's, obviously, no help to you who is probably trying to do some amount of UI work. But when you encounter similar problems with the default value of your block diagram constants, know that classes can help you in that case.

  17. Some of you have already seen this in another forum, but here's my list of sessions that I would consider to be of interest to advanced users. I think there was quite a bit of advanced topics.

    0) Steve Rogers' presentation of the new inplaceness structure

    1) Michael's XControls presentation

    2) Jim Kring's commercial software presentation

    3) Jan Klasson's presentation of the beta of the new UML editor (this is SO amazingly cool it had me drooling!!!)

    4) My presentation on Intro to OO Development (which included a new way to architect functional globals)

    5) The OO Early Adopter Stories, tales from other advanced LV users on using the new LV classes

    6) Bioacoustic Algorithm Engineering (aka using DAQ and signal processing to help with interpreting whale song)

    7) One or more of the hands-on sessions had to have had something new for you

    8) All three of the keynote presentations -- I can't even begin to cover all of them. But mind-controlled machines was really cool, and contemplating the possibilities of every person in your neighborhood having a personal aerial strike force has kept some of us in conversation for a full day.

    On the floor of the expo hall, your engineers should've been excited about

    1) S.E.A.'s new LV Localization Toolkit

    2) The inovations with the LEGO and NXT toolkits

    Further, a lot of the value of NI Week is to compare notes with other advanced LV engineers, over and beyond the sessions, and to feedback to NI on specific needs/wants. I came out of the week with multiple pages of suggested work in a much MUCH more valuable format than I get from online discussions.

    And you never know, you might come home with a new Wii. I did. ;-)

  18. QUOTE(Clicker @ Aug 10 2007, 05:12 PM)
    So if you don't mind me asking why do you need to edit the control? Does this replace the older control with a newer one?
    Normally we mark a VI as having a change when a mutation like this is made. That's not happening in this case. But the .lvclass file itself is being marked as needing to be saved. The class saves, but it isn't bothering to update its image of the .ctl because the .ctl isn't marking itself as needing to be saved. When we load the class later, it assumes that the .ctl is the same version as itself, but actually the .ctl hasn't come up-to-date. At least as far as I can tell... Without having actually fixed the bug, there may be further complications that I discover later. But the workaround should be enough for your purposes tonight. ;-)
  19. WORKAROUND FOUND.

    Load the 8.2.1 version in 8.5. Open the private data control. Edit it by resizing the VISA resource Name (actually, any edit will do). Then you can save the VI in 8.5 and it will load correctly from then on.

    Curiously, you probably (if I'm reading the code correctly) won't be bit by this bug if you load directly from 8.2, only if you load from 8.2.1. *sigh*

    This will affect any LV class that has a VISA resource string in its private data control. It is specific to the interaction of those two features.

    PS: Do you have a CAR number on this from when you reported it to NI? The bug report hasn't yet percolated to my desk, and I might as well jump ahead of the stream and intercept it at this point.

×
×
  • Create New...

Important Information

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