Jump to content

Justin Goeres

Members
  • Posts

    691
  • Joined

  • Last visited

  • Days Won

    10

Posts posted by Justin Goeres

  1. QUOTE (Eugen Graf @ Jun 13 2008, 04:08 PM)

    Why to use static dipatch member VI? It has only disadvantages to the dynamic dispatch member VI. Do it have less overhead for LV?

    I asked AQ this question at NIWeek a couple of years ago when LV82 came out. I don't remember the exact answer. I know there is a small but real (~5us?) cost to the dynamic dispatch, but it seems to me that the bigger reason is just one of coding convention. If you're debugging code where all the method calls are dynamic dispatch, then you will always be uncertain about whether a particular call is dispatching to the class member VI you think it's dispatching to. There's a real mental cost to that uncertainty, and it will make your code harder to understand.

    Using dynamic dispatch for everything can also introduce bugs into your code:

    • If you have static dispatch method Parent.lvclass:MyMethod.vi and accidentally create another method with a colliding name in a child class (Child.lvclass:MyMethod.vi) your Run arrow will break.
    • However, if you had MyMethod.vi set up as dynamic dispatch (because you decided to do everything that way), you wouldn't get any error from LabVIEW -- it would just happily start dynamically dispatching in places where you never intended it to do so.

    I mention this because I've accidentally done exactly this before, and the name collision saved me because I was using static dispatch.

  2. QUOTE (Eugen Graf @ Jun 13 2008, 01:13 PM)

    If you define a queue of type Cluster with Action-Enum-Typedef and Variant-Data inside them. Than I change my Typedef, but the queue Type will not be automaticaly updated to this "new" type. What can I do to update queue type automaticaly? Is it possible?

    If I'm understanding you correctly, you need to make the cluster itself a typedef and it will solve your problem.

    So you will have:

    Queue Type Cluster.ctl
    (typedef) containing
    Action-Enum.ctl
    (typedef)

    Variant
  3. QUOTE (Eugen Graf @ Jun 13 2008, 06:33 AM)

    It depends on the requirements of the application, and there is no one right answer. See any of the previous posts in this thread.

    Whole books have been written about this question.

    EDIT: I apologize if I am starting to sound exasperated, but really, you're pounding on a question that is way beyond the scope of this (or any other) forum. The book linked above is highly recommended for learning about design patterns in general. Everything beyond that comes from experience, and 90% of what I know about LabVIEW comes from having done it wrong the first time.

  4. The best solution, if it's at all possible, would be to wrap the vi.lib members, unchanged, in VIs of your own creation that provide the extended features you need. Even if that results in complicated or slow code, it's the most future-proof way to go about it.

    If you can't do the above, then the next best option, as tcplomp suggested, is #3. You should also make sure to use new names for any files you change so that other applications that call those files won't get cross-linked when you open them later.

    Generally, it's a really, really bad idea to modify anything in vi.lib, unless NI specifically tells you to or unless you know exactly what you're doing. In either case, whatever changes you make are extremely likely to be overwritten with the next LabVIEW update, which will magically introduce bugs into previously-working code. Insert parable about Man Who Builds House On Sand here :P.

  5. QUOTE (Eugen Graf @ Jun 12 2008, 04:29 PM)

    Why? I use it too, it's good. At all because I can unflatten it partionally and have rest of binary string (> 8.0) to parse it.

    The "Dark Ages" comment was referring to years ago before Variants existed in LabVIEW. Back then, binary strings were much more commonly used than they are today. What I meant was that if I saw a LabVIEW program written today that relied on binary strings to move data around, I would assume that either (A) it was written a long time ago, before Variants, or (B) the developer who wrote it hadn't discovered Variants yet. It wouldn't make the code right or wrong -- it would just make me scratch my head :).

    QUOTE

    I can do it more dynamic, whereby variant is more static, because you have to place variant into variant. But you can append one binary string to other binary string.

    Variants are not "more static" than binary strings. I would be willing to wager that anything you're doing with binary strings can be done with Variants.

  6. QUOTE (Eugen Graf @ Jun 12 2008, 05:08 PM)

    What do you do if your application should connect more computers e.g. over ethernet? I mean you can't use one FGV on more than on PCs.

    <snip>

    Of course, I use it. But my question was how to administrate it.

    had some projects where I used about 5 queues, 1 notifier and 7 User Events. Ok, it's not really the biggest, but it can happen, that I get a project with much more loops,where I have to administrate all references and the programm architecture.

    And of course the reusability of the code, so modularity is very important for me. I want to use some loops, tasks packed in a VI for future projects too. So I want to make it more general.

    With all due respect, you seem to be looking for a single, perfect answer to the general problem of software architecture in LabVIEW. There isn't one.

    If your application is confined to a single computer, then events, queues, notifiers, producer-consumer, and state machine designs will solve a lot of different problems. But each solution will have unique components.

    If your application requires communication among different computers, then you will need some kind of network transport, like TCP/IP. Any given solution might use some of the same tools & techniques as a local-only problem, but it will have its own twists and turns, as well.

    If you practice good coding style and use opportunities to explore the nooks & crannies of the LabVIEW Examples and the obscure corners of your function palettes, you will gain skill in choosing the right building blocks for each situation you encounter. But there's no One Right Answer. Even Local Variables have use cases.

  7. QUOTE (Eugen Graf @ Jun 12 2008, 03:02 PM)

    If my loops communicate using queues, notifiers or user events I can't choose which type of them I want to use. I use currently Binay String Type, but I saw that much people use a cluster with ENUM and VARIANT inside. The enum is the action and variant contains data. I use binary string which contains header and data.

    As Tomi pointed out, in that situation I would expect Variants to be a fair bit faster than binary strings, because the flattening/unflattening of the string data is slow. However, if you use good encapsulation and style, either approach could be used to generate readable code. If you prefer the binary strings and you're not having issues with speed, I wouldn't worry a whole lot about it.

    That having been said, if I got a bunch of code that used binary strings instead of Enum/Variant, I'd scratch my head and wonder why the original developer was still living in the Dark Ages :P.

  8. QUOTE (Eugen Graf @ Jun 12 2008, 01:29 PM)

    which programm architecture do you use in your projects if you use very much parallel loops, which communicates with syncronisation tools (Queues, Notifiers, User Events and so on)?

    You're right -- that's a very broad question.

    In general, I use as few parallel loops as I think I need to meet my design goals. Sometimes that turns out to be quite a few loops, but other times it's just one. It's driven entirely by the needs of the application, and there is certainly no maximum number I would ever limit myself to in principle. Expressing parallel execution is one of the areas where LabVIEW really shines.

    For inter-loop communication, I use mostly Queues and User Events.

    As far as a general design pattern, I am just coming off a long love affair with Producer-Consumer designs, but have realized that a lot of what I used to use two loops for can actually be done with just one.

  9. QUOTE (Eugen Graf @ Jun 10 2008, 02:31 PM)

    Ok, but the graph will be zoomed. Almost each point is needed. Not the whole plot, but I can`t decide which parts are not needed, it`s unknown and variable.

    If you've got that much data I would recommend calculating the portion of data that needs to be shown at a given zoom level and extracting just that portion from storage (similar to what Antoine suggested), then displaying that on the graph.

    I'm not sure off-hand if you can catch all the relevant mouse events for zooming/scrolling/etc. from the graph display, but if you can catch all the events you need, then you can trigger a refresh of the graph as necessary.

  10. QUOTE (TobyD @ Jun 10 2008, 08:30 AM)

    A friend and I once spent most of a weekend programming our HP-48GX's to play our High Schools fight song

    I just gave away an old HP-48SX (which technically wasn't mine -- I acquired it accidentally in an end-of-year roommate shuffle in college) a few weeks ago. The lady I gave it to said she was getting for her husband: "His old 48SX broke, and he keeps telling me he doesn't want any of the new calculators, so I'm going to surprise him with this."

  11. QUOTE (jdunham @ Jun 9 2008, 03:44 PM)

    This absolutely applies to LabVIEW.

    I'm with Jason on this, but I think the original statement was maybe a little too forceful :D .

    I refactor my code for readability continuously as I write it. And I (try to) always fix all known bugs before writing new code. However, I (almost) never optimize my code for speed or memory use or anything else but readability until I can identify a specific need to do so: It is more important to have readable code than fast code, and you can sacrifice one for the other later.

    None of which really addresses Eugen's original question ;). But AQ took care of that, so it's all good.

  12. QUOTE (crelf @ Jun 9 2008, 03:54 PM)

    Back in high school I screwed up while changing the batteries in my TI-85 calculator and cleared the memory, losing a "Football" (American, not the other kind) game I'd written. It was really cool and took up something like half the memory in the calculator. I nearly cried, right there in my Great Books class.

    Then I spent the entire weekend (at an honor choir thing, for what it's worth) rewriting it from scratch. And it was better :).

    I also remember that the date it happened was 2/26/93. That's because I got home and found out the World Trade Center had been bombed, and I thought, "Gee, I guess someone else had a worse day than me."

    And that's my story.

  13. QUOTE (Aristos Queue @ Jun 9 2008, 08:25 AM)

    More exactly, the *act* of copying data can be considered a node. Wires are data. Nodes are actions. Specifically, nodes are actions on that data.

    So the dot at the junction (if you have show dots at wire junctions turned on) is (or can be) a node. How delightfully literal!

  14. QUOTE (Chthonicdark @ Jun 8 2008, 05:57 AM)

    I'm not exactly sure what you're saying now, either, so we're in the same boat ;).

    Lemme take a shot at clearing up a possible misconception: Converting the string data to an array of U8s or U16s doesn't change its value at all. It just changes the datatype of the wire holding the data. So by converting from a string to a U8 array your data goes from being

    "7E 00 1C 83 56 78 22 00 05 06 00" (a string of 11 characters, shown here in hex)

    to

    [7E, 00, 1C, 83, 56, 78, 22, 00, 05, 06, 00] (where those are hex U8 values)

    Once you've got the values as U8 (or U16s) in an array, you can use the math & array functions on them. For instance, 0x05 + 0x06 = 0x0B, whereas "05" + "06" = broken wire (you can't add strings).

    Or am I totally misunderstanding what you want to do?

    QUOTE

    Good point. In that case, yeah, you'll have to trim the string to get the bytes to line up correctly before converting it to U16s.

    All this having been said, your second attachment (the 005 one) still looks to me like you've basically got the string parsing & conversion working, no?

    EDIT: Sometimes a picture is easier :P.

    http://lavag.org/old_files/monthly_06_2008/post-2992-1212931681.png' target="_blank">post-2992-1212931681.png?width=400

    I would attach the VI but it's in LV8.5 and your profile says you have LV8.0. If you can use the 8.5 VI just say so and I'll post it.

  15. QUOTE (Chthonicdark @ Jun 8 2008, 02:24 AM)

    You probably want the String to Byte Array function. It will give you an array of U8s that you can operate on with array functions, math functions, etc., to do the rest. Note that you can also Type Cast an array of U8s to an array of U16s directly, just like your second example does with the original string data.

    http://lavag.org/old_files/monthly_06_2008/post-2992-1212928137.png' target="_blank">post-2992-1212928137.png?width=400

    Actually, come to think of it your second example is pretty close already, and you don't really need the String to Byte Array. You can Type Cast the string directly to U16s just like you're doing, and skip the String to Byte Array step. One change I would make is to cast the string to an array of U16s as soon as possible so you're using array functions instead of string functions to strip off the unneeded bytes (not for speed, just for clarity).

  16. Add my name to the annoyed column, too, although I would probably mind less if it was a company I actually didn't know very much about. Around here, we all have kind of a skewed perspective because we're all pretty intimately familiar with ni.com and the NI product lines.

    Maybe there should be a checkbox in our ni.com profiles labeled Do not EVER make a follow-up call to me based on my browsing activites at ni.com.

  17. QUOTE (Aristos Queue @ Jun 3 2008, 11:28 AM)

    I agree it seems like an odd choice on our part. Having said that, I can't resist pointing out that if you stop using clusters and start using LVClasses, you'll get a coherent data type. :-)

    I actually thought that while I was writing my earlier reply :P.

    QUOTE

    [LATER]
    Ok. After a bit of thinking, I can explain why this was done, I think. By having
    LV
    automatically unbundle the top-level cluster elements, you have the ability to have items at the top level of your event handler, so you can have common elements between disjoint user events. In other words, I can have user event Alpha with cluster "A (numeric), B (double), C (path)" and user event Beta with cluster "A (numeric), D (boolean)". If I ever have a single frame of an event structure that handles both events, the left hand event data node will show only the elements that are in common. If we treated clusters as single elements, you'd have nothing in common between the two user events. But because we unfold top-level items, you'd end up with "A (numeric)" being available in the event case.

    That's interesting, although in practice I've never wanted to do that (maybe because it never occurred to me that I could?). I still reserve my Error Cluster peeve, though.

  18. QUOTE (neB @ Jun 3 2008, 08:44 AM)

    Now that you mention it, yes there does seem to be two sets of rules applied. If we say that this is a bug and you should be able to select the cluster, then that would let us potential poke at the invisable container used in the sclar example. I wonder what I'm missing.

    That's an interesting way of looking at it. I don't look at the event data terminals as coming from some invisible container; to me they're just terminals that semantically kind of look like an unbundle :P. But nonetheless, I feel like if I create an event with a cluster datatype, I should be able to get the cluster as a whole at a single terminal in the event structure. It's particularly annoying when the event data is an Error Cluster to begin with.

  19. QUOTE (Michael_Aivaliotis @ May 30 2008, 05:15 AM)

    Ok, so some of you may have noticed the tagging feature on LAVA.

    Can anyone tell me what tags do for me that I couldn't do already with a search? I'm more than willing to give them a shot and try to like them, but I just can't figure out what they're good for and how they help me use LAVA (or LabVIEW) better. They strike me as a solution looking for a problem.

    For those of you who use (or like) tags, how do they improve your forum experience? What do I need to do to start seeing them in a different (and better) light?

×
×
  • Create New...

Important Information

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