Jump to content

Daklu

Members
  • Posts

    1,824
  • Joined

  • Last visited

  • Days Won

    83

Posts posted by Daklu

  1. [Edit: I see Omar chipped in and described the same issues I have with hitting the run button on class vis... only he did a much better job explaining it! There's two hours I'll never get back... :o )

    QUOTE (Omar Mussa @ Feb 2 2009, 04:39 PM)

    I actually wanted to build my application in a way that allowed me to simulate hardware, but when I designed it (before I had any real experience with LVOOP) I didn't really know how to do so. Thanks for the tip. I'll admit I'm not convinced the overhead required to maintain three classes as opposed to one class would have been worth it in this particular case*, but I'll certainly keep that in mind for the future.

    (*And I certainly wouldn't get approval to go back and refactor it now.)

    QUOTE (Aristos Queue @ Feb 2 2009, 05:16 PM)

    Those auto tests have no business, IMHO, running the private VIs...

    I fully agree with you. (In principle at least... I'll reserve judgement for the practical aspects of it.) It would probably help to differentiate between a developer testing his own checked-out code and turning over "finished" checked-in code to be tested by a third party, such as an automated nightly build. My comments are referring more to self-testing dev code, although it encroaches on the latter somewhat since I don't have software test house.

    QUOTE (Aristos Queue @ Feb 2 2009, 05:16 PM)

    You can always hit the run button on any VI for short, quick checks of functionality.

    I do that when I can. There are a couple issues I've encountered that sometimes make that impractical:

    1. One of the main data types I use in my project is a virtual base class. (I derived child classes from the virtual base class to implement vendor specific code for the family of devices I'm testing.) Many of my private sub vis have the virtual base class as an input. Running the sub vi directly instantiates the base class, which of course throws an error when a virtual method is called.
    2. Even if I have one of the child classes, some sub vis need the input classes to be in a certain state to execute the intended code. The class default values aren't necessarily the correct ones for that sub vi.
    3. Many sub vis need to have several test cases run against them to get good code coverage. It's a pain for me to try to remember all the combinations of inputs that need to be tested and what their outputs should be. I'd much rather just click a button to test them.

    Those issues have led me to building many test vis for private vis that include setup, input/output comparisons, and teardown. (I'm looking forward to using the test framework!)

    --------------------------------------

    FWIW, in my second post bullet #2, more than any of the others, is what drives me to test private sub vis. If the public vi doesn't have a testable output, how do you verify it? Case in point: My project uses NI Motion to control a robot. Several of my public vis are broad 'action' vis, such as to execute a specific test. Buried several layers down in the private sub vis are a set of functions that take data from the public vi's front panel, the motion controller, and the device being tested to create an array of positions for the robot to move to. The public vi doesn't have any outputs other than a few pass-through inputs and an error out indicator.

    From the standpoint of only testing public vis, I don't see a realistic way of making sure that set of vis is functioning correctly and creating the coordinates I expect. As it turns out, there was a bug that caused the coordinates to be off by a couple mm, but under most of my test conditions it wasn't noticable while watching the robot. I found it when I was doing some tweaking and happened to increase the spacing between each robot coordinate. Then the error became large enough for me to notice.

  2. QUOTE (jdunham @ Feb 2 2009, 09:41 AM)

    I'll tell you why *I* write test cases for private vis, but I'll leave it to those smarter than me to debate the 'correctness' of doing it. :)

    The short answer is sometimes I make changes to private vis that inadvertently 'breaks' (as in it still executes but doesn't operate correctly) my application and it's easy to run a test case on a private vi to make sure it's behaving the way I expect it to.

    The long answer is multifacited:

    I'm always willing to learn better ways of doing things if they address these issues.

    QUOTE (Aristos Queue @ Feb 2 2009, 02:54 PM)

    Given all this, if you test your private VIs, you're going to become aware of defects that don't matter, and you'll waste development time fixing them.

    Only if you first waste development time broadly implementing tests that don't matter. At some point you have to trust the developer to know what needs to be tested and what doesn't in a given vi.

    QUOTE (Jim Kring @ Feb 2 2009, 10:32 AM)

    Another strategy (aside from making the test VIs members of the class under test) is to put anything that needs to be tested outside of the class under test. For example, if they are generic support functions, you could put them into another lvlib and make them public.

    That doesn't work so well in my case--the sub vis I want to test tend to be very specific to the class or library I'm creating. They aren't meaningful outside of the context of the class.

  3. JKI's newly announced VI Tester prompted me to finally post a question that's been on my mind for several months...

    I often write test vis for a class' private subvis which obviously requires me to put the test vis in the class. I don't really like distributing test code with the class. Manually removing the test vis from the class for every build is a drag. (...and drop too!) I use OpenG Builder and OpenG Package Builder for my code; I believe it is possible to write a vi that will remove test vis from a class that I could use as a pre-build script, but I haven't had the time to really dig into it.

    What are some strategies others use for testing private class vis, with or without the OpenG packages?

  4. QUOTE (Aristos Queue @ Jan 1 2009, 09:20 PM)

    You can actually get rid of the Value Changed event case and the shift registers entirely by just moving those FPTerms outside the event structure...

    Since they are all Value Changed events, I'll make the bold assumption you're referring to the X and Y Value Changed event. :laugh:

    I'm wondering why you suggested that particular refactoring. How would the compiler treat the current code differently if we pull the x and y terminals out of the event structure? I assume it would do as coded and assign the front panel value to a memory location on every loop? Any idea how that overhead compares to the overhead of monitoring an event?

    I only ask because I tend to use these manual "optimizations" as well since I don't know smart the compiler is and from what I've read it's "better" to put something like changing the x and y value in an event rather essentially polling them on every loop. (Obviously there will be very little performance difference in this particular example. It's more a question of style and principles.)

  5. I could be wrong, but I don't think there's a way to directly recast a parent object into a child object. I would have tried the same thing you did--create a child object with a copy of the parent data. AFAIK that should work as long as you have the correct methods exposed. What error did the compiler give you when you tried this?

    This link [http://decibel.ni.com/content/docs/DOC-2875] doesn't directly answer your question, but it sounds like you are implementing a Factory Pattern.

  6. QUOTE (san26141 @ Nov 18 2008, 02:49 PM)

    No, what you are showing is not inheritance. You are including Class_X and Class_B as a private data members, which is called aggregation.

    QUOTE (san26141 @ Nov 18 2008, 02:49 PM)

    1) When I have to "INIT" Class_B from within Class_A:Init how does each instance of Class_B get its own unique parameters?

    You can't in your example (assuming the parameters are not already contained in the class data.)

    QUOTE (san26141 @ Nov 18 2008, 02:49 PM)

    There are two ways:

    1. If you want to assign parameters to the Class_B object in Init.vi you need to create an input to the vi and wire unique inputs to each instance of it.
    2. Store the parameters as private class data, and create accessor method VIs to manipulate the internal parameters. For example, you could have a numeric control named com_port to store the com port number. Then you would create a Set COM Port vi and a Get COM Port vi to write and read the private data. You would use Set COM Port at some point prior to calling Init.
      Then, within Init.vi, you can unbundle the private data and use the com port number associated with that particular object rather than relying on Init.vi input parameters.

    QUOTE (san26141 @ Nov 18 2008, 02:49 PM)

    3) Can the input lines (blue arrows below) be used to tell the method which parameters to initialize the calling instance?

    The "input lines" you are referring to are in fact object wires, and carry all the information pertaining to the object on the wire, including the values of all of that object's private data. So the quick answer is yes, the object wires can indirectly tell Init.vi which parameters to use (although it's probably in a different way than you intended.)

    QUOTE (jdunham)

    Usually a LabVOOP Initialize method does not take a copy of the class in, and therefore is an initializer because the new wire out is the first time that object's wire and the data its holding comes into existence.

    If you want your initialize method to be inheritable it needs to have a class input, otherwise LV doesn't know which class initialize method to call.

    (FWIW my initialize methods are reserved for initializing hardware. I use create new methods when I was to control how new objects are formed.)

  7. ...because the best way is clearly to use VIPM. However, since I don't have that option atm I'm wondering what the second best process is. I'm attempting this using OGPB (OpenG Package Builder), but I'm interested in any solutions people have come up whether or not they use OGPB.

    What I've done in the past is build my code and put it in the installation directory, then use the Edit Palettes... function from within Labview to create the mnu file. That's really cumbersome to maintain so I'm trying to come up with a solution that allows developers a way to design the palette at design time.

    My main functionality uses VI Refnums and the newly released Palette VIs to create a mnu file when I run OGB (OpenG Builder) via a post-build vi call. This part works great and correctly handles the build process name mangling and file relocations. Unfortunately the mnu file in my build directory doesn't link to the correct files when I move them to the install directory. (Duh.) When I tried using a similar post-install vi call in OGPB it didn't work, as the post-install vi seems to be executed from a temporary directory and it couldn't find the sub vis needed to build the mnu file.

    I looked at the OpenG dynamic palette api for a while but couldn't quite make sense of it and didn't find any examples of it being used.

  8. QUOTE

    That is so sad - I'm sorry to hear that your managment is like that.

    My experience is that management in most places is like that. VIPM isn't required to do the job, it just makes certain aspects of it easier; therefore it is an unnecessary expense. On top of that Labview isn't that widely used in my group...

    QUOTE ( @ Oct 28 2008, 11:34 PM)

    10 licenses for the price of one.

    10 for 1? That I might be able to sell, but I didn't see the offer on the VIPM website.

  9. QUOTE (crelf @ Oct 28 2008, 09:30 PM)

    As much as I'd like to use it, cost is the barrier stopping me from using it. Yeah, it would pay for itself by saving me time, but my incremental cost is somewhat hidden while cutting a PO for n VIPM licenses is sure to raise a few eyebrows.

  10. QUOTE (jlokanis @ Oct 28 2008, 06:10 PM)

    I use the OGB namespace feature to build .LLB files for sets of plug-in VIs. The LLB contains all the top level plug-ins and all of their sub vis, namespaced to the name of the LLB.

    This way, I can call plug-ins from more than one LLB at the same time, each with different revisions of a common sub-vi and be sure that the plugin loads with the version of the sub-vi it was tested and released with.

    I do not think you can do this with LVLIB files. I don't think this is what they were intended to do. A source file on disk cannot be a member of two different LVLIB files. In my case, i want to build my LLBs from the same set of source sub-vis but lock down the version I built with so I don't have conflicts when using multiple versions from my app.

    I think I'm following you... it sounds like you are building LLBs to take a snapshot of your reuse code and by using the snapshot in your application code you avoid breaking the app with future changes to your reuse code. You avoid conflicts by giving each snapshot a unique namespace via OGB. If that's correct, couldn't the same thing be done by copying your reuse code to a different location and wrap it in a uniquely named LVLIB, since, as near as I can tell, that's essentially what you're doing with the LLB. (With the obvious difference that you're wrapping it in an LLB instead of an LVLIB.) What am I missing?

  11. QUOTE (Aristos Queue @ Oct 28 2008, 04:25 PM)

    OGB = OpenG Builder. (I edited the OP for clarity--I used only the acronym the first time around.) OGB creates namespaces by appending suffixes to filenames when the code is built.

    QUOTE (Aristos Queue @ Oct 28 2008, 04:25 PM)

    A library is a namespace. There are many types of libraries. Among these are the .lvlib file and the .lvclass file. So, yes, there is already a namespace for the VIs in the class. Now, if you want to namespace the class itself, put the class into a .lvlib.

    So if I understand the ramifications correctly all of the following are true...?

    1. Assume I have a Boat class and a Car class that are independent of each other. Both classes have a Start method. I am safe using these classes within a single project since the two Start vis belong to different namespaces.

    2. Assume I have one Honda class that inherits from a Car class and another Honda class that inherits from a Lawnmower class. Since the class itself isn't namespaced, I'll run into conflicts if I try to use both of these classes in a single project, regardless of whether or not they have any common vi names. (If this is true, that implies namespaces don't propagate down through a class hierarchy. i.e. Instead of Car.Honda(.Start.vi) the namespace is just Honda(.Start.vi.))

    3. VI filenames are independent of the namespace that contains them, therefore VIs with different namespaces may have the same filename and I may run into occasional conflicts if I'm not careful to separate my namespaces into different directories in both source and distributed code.

    Are there other namespaces outside of .lvlib, .lvclass, and (presumably) .llb files?

  12. I've been using OpenG Builder for several months for distributing my reuse code to myself. All along I have been using OGB's namespace feature. A couple weeks back I was demonstrating OGB to some coworkers and the one of them raised the question, "Why not just use the .lvlib namespace feature?" Aside from the extra step of wrapping all my reuse projects in a lvlib to make use of the namespace, I didn't have a good answer. Anyone want to take a stab at comparing/contrasting the two namespace implementations?

    Tangential question: Do LVOOP classes automatically generate their own namespace making OGB and lvlib namespaces unnecessary?

  13. QUOTE (Aristos Queue @ Oct 23 2008, 10:07 PM)

    Classic post. And I'll bet it took you all 1 hr 6 minutes to write it. :)

    (It was time well spent.)

    QUOTE

    Why not? As you pointed out, you can't hardly be n'americun without having made one up. Besides, once you make it up you can trademark it and make millions.

    QUOTE (Aristos Queue @ Oct 22 2008, 04:11 PM)

    The word is "sourcenders". For any given project item under Dependencies, sourcenders are those project items under Source that, as a result of some chain of dependencies, are the reasons that the original project item is included under Dependencies. Or, to put it another way, in any given chain of dependencies, sourcenders are the last items that are under Source and the rest of the dependency chain past that point is listed under Dependencies.

    post-7603-1224877461.png?width=400

    I'm glad you're looking into this. On more than one occasion I have accidentally pulled in an incorrect dependency and had to spend considerable time finding the guilty vi. (For instance, accidentally using source reuse code instead of distributed reuse code.)

    I think, however, that you are aiming at only half the target. In the example given asking for the sourcenders of E returns B, C, and F. The problem is that I can't find E anywhere in B or F so I end up having to dig deeper to find and break the dependency. What the user needs to know is the location of the bridges between source and dependencies. In order for a bridge to be a bridge, it must have anchors at both ends. (Otherwise it is a ramp...)

    In use, I could pop up on E and select "Find Bridges" which would return the anchors for each bridge. Perhaps something like...

    F.vi <--> D.vi

    B.vi <--> D.vi

    C.vi <--> E.vi

    Ideally "Find Bridges" would work on more than just a single vi. I'd love to be able to pop up on a class or lvlib and Find Bridges. Using "Find Callers" on them doesn't work so well...

  14. QUOTE (jcarmody @ Oct 15 2008, 02:59 AM)

    I'm accustomed to receiving specifications, not writing them, so I'd like to get someone else's perspective.

    Who knows better what a spec should contain (i.e. how to write it) than the person who has to use it to implement tests?

    Ideally, specifications (engineering requirements) flow naturally from product definition (customer requirements.) My experience is that poorly-defined and changing specs are often due to an inadquate product definition. Unfortunately marketing/product planning has no idea how to properly define customer requirements. (I've seen the requirement "our product needs to perform as well as competitor-x" too many times to count.) In my opinion, you're not going to get a good specification unless design and test are involved at the very beginning of the project, when marketing/product planning is first defining the product.

    In other words, a document template probably isn't going to help you much. It sounds like there are deeper organizational problems there. (I spent 5 years at my last job trying, without success, to get into the product definition phase so I could help them create a meaningful product definition.) In fact, spending your political capital on applying a band-aid to a broken arm could end up hurting your work reputation.

  15. QUOTE

    Wow - cat owners are an angry bunch :D

    I'm a cat owner by marriage, not by choice. Besides, I was rather hoping the cat would choke on it... :)

    QUOTE

    The project window should show you the missing VI, with a bright yellow symbol next to it to make it easy to spot.

    I've had this error occur a couple times in the past and I have never had the missing vi show up in the project window, either in the class it is missing from (else it wouldn't be missing) or in the dependencies (as there are no other vis that are dependent on it.)

    QUOTE

    Believe it or not, at the point where that string gets generated, I no longer have access to the object itself to get that file name.

    When I calm down and think rationally I'm sure, as you indicated, there are valid reasons specific perceived flaws are the way they are. Improving software based on 20 years of legacy code is no mean feat. I really don't fault anyone at NI for Labview's shortcomings. Like I said, I was extremely frustrated and needed a way to vent so I could continue working. (Although I am surprised it is something you have looked at changing... is there anything you don't have your fingers in?)

    Now I have to think of a different way to dispose of a cat...

  16. Grrrr... If Jim Trouchard were here right now I'd poke his eyes out and feed them to my cat. :angry: WHY DO I HAVE TO SAVE MY PROJECT TO SCC EVERY FRIGGIN' 5 MINUTES TO PROTECT MYSELF AGAINST LABVIEW CRASHES!? :throwpc:

    Some days I spend more time fixing problems from crashes than working on code. It certainly doesn't help my efforts to promote Labview when I have to tell my manager I spent the entire day trying to recover and rebuild code I had already finished... again.

    The latest crash left me with the error, "This class is missing one or more member vis." Yeah? Thanks for noticing, but how about if you tell me something useful, like WHAT THE NAME OF THE MISSING VI IS! Telling me a class of 150+ vis is missing one vi is enough to make me... want to feed JT's eyes to my cat.

    Words simply cannot express how &%*()# mad I am right now. But since I can't start yelling and throwing things this is about as good as I can do right now. (And it's woefully inadequate.)

  17. Here's one that has me scratching my head...

    I would like to have a string indicator show the contents of a string control and update while the string control is being edited. I've been playing around with it a bit and the 'Value Changed' event doesn't fire until the control loses focus. The 'Key Down' event might work if I tracked keystrokes during editing, but it looks fairly tricky. (And I'm not sure how I would determine initial cursor position or cases where the user changes cursor position via the mouse.)

    I get the sense I'm making this much more difficult that it needs to be.

    post-7603-1222232926.png?width=400

  18. QUOTE (crelf)

    When was the last time you reinstalled everything, from the OS up? I find that a reinstall once every year or so helps...

    Not that long... maybe 5 or 6 months.

    QUOTE (crelf)

    That should be fine. How complex are your classes?

    Most of them are not that complex at all. It ranges from 5 to maybe 50 (at most) VIs. I have three different class trees with my main top level classes containing the base class of the two other class trees as private data.

    QUOTE (crelf)

    Probably not. I agree that the first place to look to speed up your system is to up the RAM, but unless you've got some much going in the background that your virtual RAM is being used extensively, then it probably won't help. Besides, 2Gb is plenty of RAM for general use.

    That's what I thought. After a little more digging I found one of the svchost processes occasionally takes over the processors and had nearly 12 million page faults. THAT can't be good for performance. It's odd though... Task Manager indicates I never hit 2 GB of memory use, yet it appears things are still being paged to disk.

    QUOTE (crelf)

    Oooo - that's a really good point. ...and it should force you to do a reinstall of everything too (see above)
    :)

    Yes, that is a good point that I hadn't really considered. Investing in a nice 10k rpm drive should help things considerably. I think my notebook disk is using an old phonograph motor.

  19. So my Dell Vostro 1500 laptop is struggling while running the Labview dev environment. I suspect data is moving at near light speed which is causing time dialation :rolleyes: and means from my perspective everything is veeeeeeerrrrrrrryyyyyy ssssllllloooooowwwww. Something as simple as activating a context menu by right clicking on a wire means I have to wait ~5 seconds for the UI to respond. Trying to enter or exit palette customization mode means I get a good 15+ seconds to get up and stretch.

    Admittedly I usually have lots of other background processes running simultaneously and the slowdown isn't limited to Labview. It takes a good 5 minutes for my comp to boot and load Outlook. I'm really curious about what real world performance others have experienced when upgrading hardware/os. With that in mind...

    • I know part of the sluggishness is due to dated hardware, but I have seen comments about Labview slowing down when multiple classes are loaded. With better hardware does Labview performance scale similarly to other applications or are there some inherent inefficiencies within Labview source code that cause the dev environment to perform poorly? (My current project has only 8 classes and one lvlib.)
    • Conventional wisdom says the first thing to do to improve system performance is increase RAM. I have 2 GB currently but in XP the usable memory is limited to 3 GB, leading me to think I should move on to Vista to take advantage of a full 4 GB available memory. Is the extra 1 GB going to make much difference?
    • Does LV run in 64-bit OS's, and if so, does it benefit much from the increased memory that is available?
    • Has anyone run into issues with developing applications in Vista and deploying them to XP computers, either as executables or as applications running in the dev environment? (Other than font changes.)
    • Is the Labview dev environment designed to take advantage of multiple processors? My laptop has two cores but still runs like a dog. Does LV itself benefit from quad core processors? (Again, I'm referring to the dev environment, not LV applications I write.)

  20. Just to follow up and record information for future readers who may have the same problems I did... (Thanks to Ton for pointing me in the right direction.)

    I don't have the Professional version of VIPM and the limitations of the Community version made it inadequate for my requirements. I ended up spending several hours with the OpenG Builder and figured out how to use it to distribute "released" code to my user.lib. It appears to do everything I need quite well. There are many ways to customize the distribution. If anyone is not using OGB, I highly recommend looking into it. It is much better than Labview's Application Builder. (Though OGB does require Application Builder to compile executables.)

    I decided to create a single project file for each class inheritance hierarchy. When I make changes to any vis within that project the entire hierarchy is re-released to my user.lib. On the dev side each project file and hierarchy is wholely contained within a directory with a version number for a name. (i.e. \MyDevProjects\Toaster Classes\v1.00\Toasters.lvproj ...) I do NOT include version numbers in the name of any source code vis. When I need to make a minor rev I simply copy the folder and rename it with a new version number. (i.e. \MyDevProjects\Toaster Classes\v1.01\Toasters.lvproj ...) This makes it easier to keep track of what version I'm working on at any given time and allows me to view multiple minor versions simultaneously during dev, as long as the minor versions are in separate projects. Since all the files are wholely contained within that directory structure OR reference vis from user.lib, there are no broken links in the new version.

    As Ton mentioned, OGB has the ability to append suffixes ("namespaces") to filenames during the build to guarantee uniqueness while at the same time maintaining all the links. I decided on a namespace that includes major version number in the code released to user.lib. (i.e. "MyToasterVI__toasters_v1.vi") If I make a change to a class that breaks backwards compatibility I'll increment the major version. This allows me to use multiple released major versions of the same hierarchy at the same time. Minor versions and bug fixes are automatically integrated into any vis that use that class hierarchy. Minor versions *must* be backwards compatible so I don't anticipate needing to use more than one released minor version at any time.

    I have 4 class hierarchies and one lvlib that were all linked within my dev directory. Once I figured out how to use OGB it only took me ~6 hours to break them apart, create build files, and relink to the correct files in user.lib. Much less than the 30 hours the previous exercise took.

    There are a couple things to look out for though:

    1. Take the time to figure out where the leaves of your calling tree are and work on those first. When a vi uses a vi/ctl from another hierarchy or library, that hierarchy or library already needs to be distributed to your user.lib. This is obvious once you run into the problem, but may not be obvious when you start.
    2. Take the time to think about the long term consequences of your distribution scheme. I decided to distribute my classes to user.lib by maintaining my subdirectory structure instead of as an llb. This would get me up and running quickly while maintaining some level of palette organization. I realized after the fact that once I release a public vi in a certain location I can't move it without creating a maze of destination exceptions.
      Since I frequently change the locations of source files during dev I'm going to have to go back and change the distribution to an llb and relink all my dev code. I believe this will allow me to arbitrarily change source file locations without affecting the released code in user.lib. I'm also going to release it to \user.lib\_MyTools\... and create custom palette menus for each class. More work up front... easier long term maintenance and usability.

    Hope this helps someone else through the pain of figuring out how to organize projects.

×
×
  • Create New...

Important Information

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