Jump to content

PJM_labview

Members
  • Posts

    784
  • Joined

  • Last visited

  • Days Won

    10

Posts posted by PJM_labview

  1. OK, I think of myself as a bit of a Labview geek, but I don't get what's so cool about variants. Obviously sometimes you have no choice but to use them, database stuff in particular. But otherwise, why convert from other types to variant?

    Also, another person implied that variants are an alternative to passing data by wire. How?

    With variant you can write generic utilities that will take anything as an input. From your statement I suspect that you are not using the OpenG variant tools. As an example, the OpenG variant configuration VIs allows you to read and write ini file with an extreme ease (compare to the native LV way) [see image below].

    post-121-1158251634.png?width=400

    I have seen them beeing used (or used them myself) for many generic utilities such as XML tools (controls --> XML, XML --> controls), generic logger tool, a pyhton data to LV data and LV data to python data tool and many more.

    PJM

  2. Hello all !

    I've recently registred with these forums, my first PM by M. Aivaliotis (not sure if this is an automatic one, though) was advising me to introduce myself here, so here I am.

    I'm not a computer scientist but, I'm a physicist (specialised in optics). I've been using LV for a few years, in order to develop and bring automation to optics experiments for R&D purposes. Over the years, I've become more and more interrested in this part of my work.

    I've started to be really interrested in "wire engeneering" and code efficiency this year, after having had real trouble doing what I wanted with limited hardware resources. I've been pointed to the LAVA forums by someone on NI forums, while I was talking about optimization and execution speed. Reading the archives have really been usefull to me : thank you all for this.

    I hope to be able to take an active part in discussions and to contribute code, I really like the idea of open LV code. Finally, I'm not a native english speaker, so I hope you'll forgive me for the poor-man english.

    Ok, back to work now, I have an awfull diagram to clean :(

    Welcome as well.

    And if you have a real need (although looking at your english I dont think this will happen) you might even get some answer to question asked in french (some of us have a vocabulary that extend beyond "merde" :P ).

    A bientot.

    PJM

  3. I'm very concerned about these cases. A lot of stuff breaks when one VI breaks, but that one VI should be readily findable with the red X and I'd hoped that the errors there were sufficiently explicit. Was the error list window not descriptive? What were these errors?

    Unfortunately I did not keep the code since I had to rewrite everything. But as best as I can remember it happen when, out of frustration, I try to copy 2 VIs from a class residing in a lvlib into another lvlib (note: I was working on a copy of the lvlib with the same class data). After reopening the new lvlib and remarking the copy VIs as belonging to the lvlib, I got 3 VIs with red x (the original one that was broken before + the 2 I add to the lvlib). I think I fix one of the red x, but eventually I could not fix the other 2 red x.

    In order for any VI in Class X to run,

    A) every dynamic dispatch VI in the Class X must be runnable.

    ...because we have to build the dynamic dispatch table of compiled VI pointers in order to have runnable data on the wires. Trying to only reserve certain positions in the dispatch table turned into a nasty mess that wasn't really maintainable. When you hit the run button, we were traipsing through call hiearchies, including all possible dynamic dispatches, searching for any call that might invoke a given subVI and then figuring out which position in the dynamic dispatch table that subVI occupied and thus all classes needed to be able to reserve that position.

    B) X's parent class has to be runnable.

    ...because the child is a parent and depends upon the functionality of the parent. By induction, this implies all ancestors of X must be runable.

    C) all classes that are members of Class X must be runnable

    ...because those classes are part of the data of X.

    D) all classes that are children of Class X must be runnable

    ...because controls of Class X can contain child data and there's no way to detect when we hit the run button whether or not such data exists.

    E) we have to lock all members of Class X (even the static ones) so that you cannot edit them because if you were to edit a static VI to be dynamic while the classes were running, this would change the indexing of the dynamic dispatch table.

    This is a burden for LV that I'd like to decrease, but I would like to point out that in most languages the entire hierarchy has to be runnable for anything to work. We were able to maintain the individual runnability of VIs, but everything has to be *able* to run.

    See above for why so much breaks. As for the cycles, the dependencies list is cyclic and its hard to get descriptive error messages propagated so that everything is reporting the real reason for its breaking, especially when there are multiple things really broken. Again, that's why the red X modification was so important to get in this version.

    There are certainly improvements that can be made in the future.

    From your detailed answer (thank you), I gather that in all instance (while debugging classes) the only errors to pay attention to are the one marked with a red x and everything else is basically broken because these red x errors; if this is correct, then why do I need to see all the other errors? this just add to the noise and does not make my job any easier.

    PJM

  4. ...

    On the down side, when I upgraded, I found it acutely painful to develop in 8 due to the random palette reorganization. I don't think I exaggerate when I say it probably cost me a couple of weeks of work time (i.e. for the first month, it took me twice as long to program things as it should), until I finally got irritated and manually re-wrote the entire palette set (which brings up an entirely new set of problems, since the editor seems to have gotten flakier and I still can't find the option to save multiple palettes on the same machine).

    ...

    Have you check VI Package Manager?

    It allows to install the OpenG Goodies, and you get for free, among other things, a LabVIEW 7.x palette. See attached picture.

    post-121-1156914548.png?width=400

    PJM

  5. Take a close look at the Error List Window. The items at the top (scroll to top) have a Red X next to them. These are where the real breaks are. Everything else is broken because of one of these.

    This is a fix that applies even to subVIs in deep hierarchies. This UI feedback should help with a lot of the "drill down the hierarchy" type problems.

    I know about the red X, but why does VIs in the class that have no dependency whatsoever (whith the broken VI) are broken?. Basically, every member in the class is broken (and if you follow the error path [from VI to VI] you end up in a recursive list of errors). Why?

    Also, I end up in situation with several VIs with a red X where I was not able to figure out what was wrong.

    In my opinion, the class debugging is so poor that this greatly limit LabVIEW OOP usability.

    PJM

  6. I don't use express VI's and I admit I was very dissapointed to see the file dialog function dissapear only to be replaced by an express VI. Perhaps more annoying than this is the fact that they added a new feature that is only available via a configuration page. I'm talking about the multi-select.

    post-2-1156833806.png?width=400

    So you think that if you break the express vi you will get the primitive with the multi-select as a wired input? Nope. You STILL have a property page. What's the solution? You end up creating your own wrapper that allows the wiring of the selection mode.

    post-2-1156834219.png?width=400

    I could not agree more about the file dialog express VI.

    On a side note, it saddly seem that in the latest LV version, primitive overloading through right click option is getting to be the norm.

    So on answering your question

    1) No I did not use it. But to access the primitive this is a pain (drop express) right click to see bd, open subVI and finally copy primitive.

    2) I prefer small icon. Why: Real estate. As a style, I dont like code that waste space.

    3) No

    4) I use the daq assistant express VIs before generating the LV code form it (actually this is a pretty handy one)

    PJM

  7. Thanks for testing the maybe-not-bug. I tried again and this time it works every time on both computers every time! Really weird :blink: . When I found the maybe-not-bug I verified this after restart, on two computers and at least ten times and with different icon files and new and old project files. It must have been something interfering with our systems or so. The only thing I can think of is that Windows have automatically installed updates since I tested this the last time.

    So, this is probably not a bug and I'm happy, but if someone gets the same issue please reply.

    Hi,

    I believe, I had this happen to me once or twice (but on LV 8.01). A restart of LV did fix the issue.

    PJM

  8. Is there a way to create names for unnamed wires before they are bundled so Unbundle By Name can be used? I have 7 image wires coming out of a subVI, and I am wanting to modify the subVI to output only a cluster of the images so it can be passed around the main app easier. I experimented by bundling the outputs (outside the subVI). Unbundling that cluster by name works (the wires are named the same as the outputs of the subVI). So I tried bundling those same wires within the subVI, passing the cluster out, and then unbundled by name outside the subVI. The wires are all named "New Image" because (I'm assuming) that's the name that the "IMAQ Create" VI outputs are inside the subVI. I suppose I could nest my subVI inside another which only bundles the image outputs of the first subVI. If I can't figure out another way of doing it, that's what I'll do. Isn't there a better way?

    Thanks,

    Brad

    Hi Brad,

    Yes there is a way to do that. You can use the variant to data primitive. See attached image and example.

    post-121-1156830182.png?width=400

    PJM

    Download File:post-121-1156830220.vi

  9. Debugging classes is #1 on my list. It is impossible to track down an error inside a class, since a broken member causes every VI in the class to be broken.

    broken member VI ==> broken class ==> every member of the class is broken

    I've talked to others who have spent enormous ammounts of time trying to track down trivial bugs in classes.

    I will have to second that.

    I got VERY frustrated trying to debug simple LV class.

    A wire connected to the wrong input and the whole class is broken and the error windows return a huge amount of errors completely irrelevant.

    In some instance I could not even figure out what was going on and I had to recreate the class from scratch (what a pain).

    To make thing ever worse try to put a class in a lvlib... Enjoy the nightmare.

    PJM

  10. Edit: Completely rewritten to clarify the message.

    Hi,

    I wrote a by reference objects template using two separate queues; one for the private class data and the other for locking mechanism. The private object data is defined in a private typedef instead of the Class Private Data control.

    The class template also contains a constructor, a destructor and a copy-constructor. The consturcor should be renamed to Create Class Name. If there are multiple constructors, all the constructor names should begin with Create Class Name. The copy-constructor and destructor are named Copy and Close respectively. The responsibility of constructors are to initialize the queues, initialize private data members if needed and call parent constructor if class is a child class.

    There are five private methods: _Init, _Get Data, _Set Data, _Get Data to Modify and _Set Modified Data. All private and protected methods start with "_" to indicate that they are not public. Also red color should be used in private method icons instead of black to indicate that the methods are private. The _Init method is used to initialize the queues and is called by the constructors and the copy-constructor. _Get Data and _Set Data are used to get and set the private data without locking. _Get Data can be used even when the object is locked; it returns the current state of the private data. Also _Set Data can be used even when the object is locked, but it's primary use is to store intermediate values to locked object when the lock cannot be yet released. There is however no guarantee that the data written with _Set Data will not be overwritten before the lock is released. _Set Modified Data can be used to release lock and to simultaneously store modified data retrieved with _Get Data to Modify.

    All the private methods are reentrant to ensure that there is no VI level locking; that is private methods can be simultaneously called from different sources even though the object is locked and there are private methods currently waiting for the lock to be released. There is however no way I can think of to guarantee that VI level locking doesn't happen to public dynamically dispatched methods. First only single instace of each private methods is used in each of the public methods. That is if there is a private method waiting for lock to be released and this private method has been called from a public method, then this public method is locked for all the objects since no object can access this private VI simultaneously. There is therefore VI level locking which I don't think can be avoided easily. The same problem is propably with all the other concurrency control methods proposed here.

    A ZIP file containing a LV 8.2 project is attached. The project contains two libraries. The first library contains the template and the second library contains an example how to use the template. I think also inheritance can be worked out, but I haven't tried it yet. I'll investiage it later either tomorrow or next week.

    I hope this helps people to get forward with by-reference objects and also clarifies why I have very strongly requested the addition of built-in constructors, copy-constructors and destructors. This example wouldn't work without all these.

    Download File:post-4014-1156620139.zip

    Edit 2: There are a few items that still needs to be worked out

    • Inheritance
    • Clean up of member objects at time out and at object close, propably separate private _CleanUp routine should be used in all methods
    • If class Close is called during simultaneous call to _Set Modified Data the data queue may be empty. How to avoid this situation?
    • Ability to create named objects, the same object can be referred in multiple places without joint wire source. Named queues will be used instead of unnamed ones. This would make it very easy to create Producer - Consumer design pattern.
    • How to avoid VI level locking, is there any workaround?
    • Can the template internal methods be somehow encapsulated into another class so that the implementation of the by-reference objects in general is not tied to the implementation of each individual class. This would allow updating the by-reference system all the time without need to update all the classes using the by-reference system as long as the interface to the by-reference system stays the same. VI level locking may be a difficult problem with this kind of approach.

    I appreciate suggestions to the above mentioned questions.

    Hi

    I like your implementation (I especially like the now obvious way you got over the data copy issue I previously had).

    Attached is a revision of this ObjectByRef class.

    Download File:post-121-1156716022.zip

    It has the following major modifications (see code for details):

    • Add support for name objects.
    • Disable the set data (I dont think this should be allowed, too much potential for major screw ups).
    • Change behavior of SetModifiedData so it always release the lock.
    • Minor changes in several other VIs (most ot them regarding the timeout input).

    I have not decided yet if the copy method is really usefull, but I left it there.

    In regards to this point:

    • "Clean up of member objects at time out and at object close, propably separate private _CleanUp routine should be used in all methods"

    I gave some though about this, and I think the timeout should return an error from within the private method whenever possible (meaning whenever we know what is the only possible situation that may have arised to return a timeout). For an example of this see SetDataToModify.

    About this point:

    • "If class Close is called during simultaneous call to _Set Modified Data the data queue may be empty. How to avoid this situation?"

    I think this is a non isue since in that situation while you may get default data you will get an error because the queue refnum has become invalid therefore you can recover if you handle this error somewhere.

    I will have to give some more though to your other points.

    PJM

    Note: any comments are of course encouraged :P

  11. I just saw this video on yahoo and....

    <embed src='http://us.i1.yimg.com/cosmos.bcst.yahoo.com/player/media/swf/FLVVideoSolo.swf' flashvars='id=715691&emailUrl=http%3A%2F%2Fvideo.yahoo.com%2Futil%2Fmail%3Fei%3DUTF-8%26vid%3D23af1dde394f5f83347374a6b24ed662.715691%26fr%3D&imUrl=http%253A%252F%252Fvideo.yahoo.com%252Fvideo%252Fplay%253F%2526ei%253DUTF-8%2526vid%253D23af1dde394f5f83347374a6b24ed662.715691&imTitle=%25E6%259C%2589%25E4%25B8%2580%25E5%25A5%2597%2521%2521&searchUrl=http://video.yahoo.com/video/search?p=&profileUrl=http://video.yahoo.com/video/profile?yid=&creatorValue=bGVlY3BfbWU%3D' type='application/x-shockwave-flash' width='425' height='350'></embed>

    WOW!

    PJM

  12. I'll upload 2 of the 5 packets I was sent, as the total size of the 5 is like 15 meg or so.

    The other issue (which I forgot to mention) is that we are using Labview 7.0 express base. I don't even know if these are compatable. I appreciate the help.

    Download File:post-5939-1156456855.llb

    Download File:post-5939-1156456891.vi

    Here are a few comments and answer.
    • The mks.llb file is missing
    • The VI appears to have been made under LV 5.0 (so you will be ok in LV 7.0 base)
    • The VI call 146chart.vi appears to be an example of how to communicate with your instrument (this is the good news).
    • The not so good news is that the code quality is poor. Finding out what's going on in this VI will not be too easy for a begginner.

    Hope it help.

    PJM

  13. This is not a direct answer to your question but more a general answer about recursion and LabVIEW.

    Typically in LV you can implement recursion in 2 ways:

    • The reentrant self Call By Reference (CBR) is the first way (this is the method you mentioned in your question).
    • The while loop stack method (Stack) is another way. In the Stack method, the work to do is store in a shift register and after every iteration of the loop more work may be added to this stack. The recursion ends when there are no more work to do. Note: The Stack implementation is almost always faster than the reentrant CBR.

    I read somewhere, a long time ago, that every recursive algorithm can be implemented using the 2 previously mentioned methods (in other word, you can convert a CBR implementation to a Stack one and vice versa) and so far it is my experience that this is true.

    So, back to your issue; it might be possible for you to convert your recursive CBR implementation to a Stack implementation.

    PJM

  14. Man! do I Love this stuff.

    Ok here is something I've been working on since the Beta version but never got there until NI WEEK gave me an Idea.

    What if we create a class That uses both the by ref model and the by Value model and then inherit the class so any class can be run as a by reference.

    What I came up with was a class called Flip-Flop. Its purpose is to move the data to either a Variant stored in a Que (By Ref) or the Child class wire itself (By Value).

    In the Main Vis the class wire data is stored in the Que and when a public function receives the wire it transfers the data to the wire so it can process it. The power of this Idea is it takes full advantage of the new inheritance.

    Please check this new Idea Out. I'm calling it FLOOP for Flip-Flop OOP.

    Download File:post-584-1156262742.zip

    And FLOOP, You got to love this name!

    PJM

  15. Bug Description:

    If you create the attached VI and put a custom probe (which happen to be a conditional string one by default) on the queue refnum wire and run the VI, LV crash (regardless of the queue element type).

    post-121-1156258219.png?width=400

    If you put a generic probe everything is fine.

    post-121-1156258386.png?width=400

    Mostly the problem arise when LV decide all you want are custom probes (even when you just select right clik>Probe [and not custom probe]) and put a conditional string custom probe by default on this type of wire.

    Workaround: Be sure never to have a conditional string probe on queue refnum wire.

    PJM

    Download File:post-121-1156258747.vi

  16. Bug Description:

    If you create the attached VI and put a custom probe (which happen to be a conditional string one by default) on the queue refnum wire and run the VI, LV crash (regardless of the queue element type).

    post-121-1156258219.png?width=400

    If you put a generic probe everything is fine.

    post-121-1156258386.png?width=400

    Mostly the problem arise when LV decide all you want are custom probes (even when you just select right clik>Probe [and not custom probe]) and put a conditional string custom probe by default on this type of wire.

    Workaround: Be sure never to have a conditional string probe on queue refnum wire.

    PJM

  17. Attached is another version derivated from Jim version 3.

    Download File:post-121-1156222854.zip

    It has the following new functionalities:

    - GetData is fully asynchroneous (it will not be locked by the GetDataToModify and it will always return data).

    - Access to named object from asynchroneous process through the create.vi.

    Drawbacks

    - To be able to have a fully asynchroneous GetData another queue is used with a copy of the data (if someone can figure out a way to get this without making a copy...)

    - The create is more complicated (the GetDataToModify, SetModifiedData and GetData are still very simple).

    Any comments and/or improvements are welcome.

    PJM

  18. ...

    File I/O primitives - A lot of file utility VIs were thrown out with 8.0 and fundamental changes made to the primitives that I think are flawed. 1) the default mode of the read primitive in text mode is to terminate the read at an EOL. The ability to chunk through a file line by line is great, but I don't think it should be the default. 2) You cannot set the read mode via a control or constant. The only way to change the read mode is through a pop-up. The only way to determine the read mode setting is through the same pop-up - there are no visual cues. So - I don't think the file I/O primitives have taken a step forward.

    Variants - they needed a performance enhancement! Do you have a benchmark for how much slower they are over data passed by wire in their current implementation?

    ...

    My least favorite features - the project and the arbitrary reorganization of the palettes. Each time the palettes are changed, my productivity decreases because things are no longer where they should be.

    ...

    Richard beat me to the punch!

    I have not use the matrix or the xcontrol yet (although I will certainly in the future).

    About the new file IO, they may be better, but in my opinion the implementation was not well done (and I am beeing nice saying this). The change of default behavior mentioned by richard, the primitive overloading through right click (with no change on the icon primitive) and the new icons result in a very bad user experience for me (and for a lot of other as well). That their performance have been improved might be true, but this is not what I retain from their usage. Another grip: why is "file dialog" now only an express VI! in the palette. If I want the primitive only this is painfull!

    In regard to variant, I am missing the type string from the flatten/unflatten to string primitives. This make variant introspection, in the spirit of the OpenG variant tools, pretty much no longer possible for new data type.

    Retain wire value, or "after probes" are pretty cool. It has already helped me quite a bit.

    Scrollabar on array. Well, I can see some good usage for that.

    Just my 2c as well

    PJM

  19. I am thinking of looking at Linux as a Labview app environment.

    Other than the Windows/Linux conversion differences such as ActiveX and such, what are the pros and cons of the different distros and getting Labview to work under them?

    What is your preferred platform? Please no distro flame wars...

    Mandrake (now called Mandriva) just works fine.

    I beleive NI has a recommended list somewhere (and mandrake is part of if).

    PJM

  20. OK, I found a way but this is really REALLY cumbersome. The inspiration came from an older thread in LAVA:

    http://forums.lavag.org/index.php?showtopic=105

    The idea is to have two arrays with color boxes behind each other, with the color boxes in front slightly smaller so you can see the box in the back as a frame. The box in the front array is embedded in a cluster with invisible frames so here the frame takes care of the spacing.

    Important: For the front array drag an array control to the front panel and color the array background transparent BEFORE you drag the array element inside, otherwise you won't be able to see the back array.

    This is really tedious, I wish NI would give us more control over the cluster frame.

    Cheers and :beer:

    Guenther

    post-3733-1152197309.png?width=400

    Download File:post-3733-1152197366.vi

    Guenther,

    I have had that grip about cluster frame thickness now for a long time as well. This *feature* makes array of cluster very hard to use in a UI (as you just found out). In your particular situation there is an alternate solution. Use the colorbox that has a frame for the top array. You can customize this one frame thickness in the control editor.

    post-121-1152208723.png?width=400

    See attached VI Below

    Download File:post-121-1152208599.vi

    PJM

×
×
  • Create New...

Important Information

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