Jump to content

gb119

Members
  • Posts

    317
  • Joined

  • Last visited

  • Days Won

    7

Posts posted by gb119

  1. One thing that I thought lvlibs was supposed to do was to help prevent conflicts within LabVIEW. I'm not sure if this was a problem in LV 8.6 but I'm using LV2009 now and getting a strange problem.

    In my project file, I have two different lvlibs that have a 'dir.mnu' file. These lvlibs are from 1) an Agilent driver, 2) Some NI lvlib (NI_AALPro.lvlib).

    Anybody else seen issues like this? What's the solution (my current solution is to ignore the warnings)?

    Thanks in advance!

    There are known problems with multiple non-vi/ctl files with the same name in LabVIEW libraries and classes that can result in unexpected cross-linkages between lvlibs or worse, corrupt files. See this thread on NI's forums for details.

    Essentially it appears that the loader uses the standard LabVIEW linker rules about how to find a file when loading the members of a library. Whilst this is perfectly sensible for LabVIEW VIs, custom controls etc which should have a unique name, it is less than helpful when the library files contain other types of file that may legitimately have the same name - such as dir.mnu files. This isn't a problem in project files as in that case the members aren't all loaded into memory when the project is.

    The solution is to move the dir.mnu files out of the lvlibs, or to rename/recreate them with unique names. Your current solution will go very badly wrong if you ever have multiple dir.mnu files in the same lvlib !

  2. I've run into this quite frequently. In every* case it's because there was something in my project that still depended on the item I removed. Usually I'll find the offending dependency in a diagram disable structure or buried somewhere in a case structure.

    Unfortunately Find->Callers is not a reliable way to find out if your project depends on a given item. Ironically the best way to see if you have a dependency is to remove the item from the project and see if it shows up in the dependency section. I've learned not to delete items with the hope the problem will go away. It doesn't--it just gets worse.

    If I really can't find the dependency I'll close the project, rename the file I want to remove, and reopen the project. The vi that is loading when the browse dialog pops up is the one that has the dependency.

    (*The one exception is if the removed item shifts into the 'Items in Memory' subfolder. In those cases your project doesn't depend on the removed item, but you have a non-project vi open that does depend on the removed item.)

    The really frustrating one I've encountered is when a class object has gotten saved with a child class instance as the default data. Sure the class icon on the block diagram shows up with a black border - but is it a black border because the class is the correct type but with non-default data, or is it black bordered because it's got a child class on it ? And other than opening each vi which uses a class and looking at its front panel to check for black borders, how the **** am I supposed to find which vi is keeping my child class in memory ?

    The real problem with this comes when the vi holding the child class in memory is a mehtod vi of the parent class and the child class itslef is broken. That makes the parent class broken and every single child class of that parent is thus broken as well.... you can't simply unload the really broken child class because you can't easily track its dependency, fixing the breakage might not be easy if this is a child class that is under development...:frusty:

  3. Your class hierarchy looks fine.

    I don't have any LVOOP based instrument drivers I could post, but I'm sure someone has one kicking around.

    Your class hierarchy looks basically the same as the one I'm using. Attached is my LVOOP'd driver for a Keithley 24xx Source Meter (which is a bread and butter instrument for us for any sort of electrical transport characterisation). I won't pretend that it's particularly well implemented, it was pretty much the first thing I wrote in LVOOP but it is now the basis of all the instrument communication I do. The base class provides essentially a wrapper for VISA along with some SCPI handling code and provision for realtime monitoring of what is being sent to the instrument. The source-meter intermediate class is rather tightly coupled to Keithley type instruments, but since that's what we mainly use... The actual Keithley 24xx class includes some pretty ropey code in places, but generally works as expected.

    Anyway, "share and enjoy"

    Keithley 24xx-LVOOP Driver.zip

    [edit: 8.6.1]

  4. I'm not sure what you're asking. The layout system itself is already implemented somewhere in the depths of Labview. Are you after documentation on that system to improve fp performance? Are you looking for a framework to help with resizing the fp during runtime?

    I've certainly wanted to attempt runtime resizing and rearranging of my frontpanel (for an XControl where the user can resize the facade and so I want to be able to rearrange the control elements as required).

    I had a brief look into how Tcl/Tk packing layout engines worked, but it looked quite complex so I stopped :(

  5. am try from one example and one topic in this site

    but it does not work can u help me

    i have 2 error plz see attachments

    1 more qustion plz

    i want to make a report i try that but i Fail

    Ok, your immediate problem (aside from the missing sub-vi) is that you are generating some outputs in the case structure inside the while loop, but only when that case is true. When the case is false the two wires coming out of the case structure don't connect to anything inside the false case. You can see that this is the problem because the 'tunnel' where the wire goes through the case structure boundary is white not solid colour.

    However, I suspect that you have a larger lofic problem in your code as the bit where you are trying to save the log file to disc will only execute when the whole measurement loop is finished and then will only write the very last measurement to disc.

    Your probably want to move the code that builds the table and and also save the file into the inside of the case structure in the while loop.

  6. To the best of my knowledge, there is no undocumented config token to change the behavior of the probe watch window.

    That's a shame.

    From a quick trawl through the LabVIEW folder it doens't look like the probe window is implemented in G which would have given some chance of replacing it with customised code.

    My particular irritation (aside from the lack of option to change the default float/non-float) is that having floated the window, closing it re-embeds the probe rather than having it remove the probe like it used to. I was looking for something like a toggle on the context menu on the probe watch window to re-embed the probe window which seemed like the more obvious place to go...

  7. i need to biult system that can be measure pressure from sensor i have the transfer funtion

    but i try to make it but it does not work

    i need to save data in excel file and in same time i need to display the reading of pressure in table by front panel

    table conssit of (date\time\value).

    also i need to make excle file save data day by day not all of them in same file

    It's going to be almost impossible to help you unless you give more details of the hardware that you are working with - how do your sensors connect to your computer ? What so of signal do they return ?

    People on LAVAG are generally helpful, but are much more likely to help those that try to do something for themselves first, so I suggest you post what code you've managed to write already, even though it doesn't work.

    Or you might find that asking your teacher or instructor is a more profitable route to getting solutions to your assignments.

  8. Typically I almost always use several probes concurrently when I need to debug some code (and by this I mean I need to look at several probe at the same time).

    In LabVIEW 2009, every newly created probes is automatically embedded in the Probe Watch Window.

    This really wants to be an option doesn't it ? I wonder if there is a magic ini file string that turns this behaviour on or off ?

  9. But gb119, what do you exactly need it for? Is Selected property and then first element of Terms[] property not enough to get a source of selected wire?

    This is thinking about right click framework plugins for inserting code into a wire - but if the wire is branched you need to know which bit of the branch you are trying to break into - i.e. inserting before a branch point or after a branch point makes a difference to the code.

  10. Also, the wire segments (I think) have a flags property where bit 4 says whether it's selected or not. It might also help.

    Hmmm, that all helps, but it looks like a routine that then traverses the wire to work out which terminal(s) are down-wire of a selected segment is still needed. I'll add it to my l"interesting things to look at when I have time" list...

  11. On a related topic, does anyone have a good algorithm for working out (given a set of co-ordinates) on which segment of a wire a mouse click has been made and therefore which drain terminal that segment is connected to ? This is kind of important if one wants to insert a node into a wire between the source and only one specific drain terminal.

    Terminal has a property Connected wire . You take a wire and get its Terminals[]. The first terminal in this array is always a source terminal (terminals has also Is source? property) - let's call it STerm. Now you have to go through all GObjects on the same diagram. You have four cases here: GObject is either Control, Constant, Node or FlatSequence. Two former have single Terminal property (according to AQ you can typecast Constant to Control making it one case), two latter have Terminals[] property. So for each GObject of these types you have to go through all its terminals (one or more) comparing their references to STerm. It may appear that node you found is a loop or other structure. In this case if you like to search further for the source you have to specify class of terminal reference to OuterTerminal, take Tunnel property, then its Inside Terminals[] property and recursively go further.

  12. Waveform XControl


    Copyright © 2008, University of Leeds, UK

    All rights reserved.

    Author:

    Gavin Burnell

    --see readme file for contact information

    Description:

    This XControl provides a function generator wrapped up in an XControl that outputs an analogue waveform

    data type. Supports sine, square, ramp, saw tooth, parabolic, cubic, quartic and arbitrary functions with adjustable amplitudes, offsets, and number of periods with no further coding. User interface provides a graph that updates in response to user changes to the controls.

    XControl will adjust layout as it is resized, and provides properties to set the visibility of the axes scales, y=0 marker and a current index position marker.


    • Submitter
    • Submitted
      07/04/2009
    • Category
    • LabVIEW Version
      2018
    • License Type
      BSD (Most common)

     

  13. I've just uploaded a new version - 0.20.1 which has several new features, including a vi that can create structures by enclosing objects that already exist on the block diagram - just like the regular draw structure around things does. There;s also a couple of vi's that do things that aren't exposed by scripting - like turning on the "use default if not wired flag" on tunnels and triggering type propagation. I've stuck these together to create a new example too - a pugin for the JKISoft RCF framework that will wrap everything in a case structure, wire up the error wires and then set the output tunnels to use default value if not wired (so the resulting VI does actually compile).

    • Like 1
  14. index.php?app=downloads&module=display&section=screenshot&id=84

    Name: Generate Palettes

    Submitter: gb119

    Submitted: 21 Jul 2009

    File Updated: 15 Oct 2009

    Category: LabVIEW IDE

    Version: 1.0.04

    LabVIEW Version: 8.6

    License Type: BSD (Most common)

    Generate Palettes-1.0.0.04.zip

    ~~~~~~~~~~~~~~~~~~~~~~~~~~

    Copyright © 2007-2009, University of Leeds, UK

    All rights reserved.

    Author:

    Gavin Burnell

    G.Burnell@leeds.ac.uk

    Distribution:

    This code was downloaded from the LAVA Code Repository: http://lavag.org/index.php?app=downloads

    Description:

    This is a utility for automatically creating palette menu files from a library or LabVIEW class.

    LabVIEW offers the option of including palette files in .lvlib or .lvclass files and for setting one of these palettes to be the default palette file when the user right-clicks by a member vi or class wire. This is very useful, but the LabVIEW project manager has some flaws when it comes to

    having multiple palette files with the same name in a project that can easily result in a corrupt xml file. This utility gets around this problem by creating uniquely named palette files that reflect the project structure of the class or library.

    In the case of class files, if the class is a child class the utility will attempt to lcoate a palette file for the parent class. This makes it easier to have all parent methods readily to hand when right clicking on a class wire. Couple with the option to work out the complete class parentage and create all necessary palettes it is quite easy to setup a chain of palettes through a long descendent list of classes.

    Todo:

    I've got various ideas to implement in future versions:

    1) Look for gone away or moved items in the palette files and attempt to relocate them.

    2) See if I can access Endevo Goop Developer class properties to use different icons for public/private/protected class folders.

    3) LabVIEW project file support (should be quite easy to find all class, library files within a project)

    Dependancies:

    OpenG File Tools

    Support:

    If you have any problems with this code or want to suggest features:

    <LAVAG forum here>

    h

    Change Log:

    1.0.04 Fixed silly bug where default palette was set after the library was saved. Sorted out relative paths somemore.

    1.0.03 Added code to set default palette file (thanks to Ton Plomp !) and move refresh palettes to only run once.

    1.0.02 Added some more documentation to the sub-vis.

    1.0.01 Original release

    License:

    Copyright © 2007-2009, University of Leeds

    All rights reserved.

    Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

    * Neither the name of the University of Leeds nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR

    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR

    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,

    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR

    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF

    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

    Click here to download this file

  15. Now, what happens if, on the diagram of B:Increment.vi, we wire a C object directly to the Call Parent Method node? When we call "Get Numeric.vi" on that C object, we get the answer "1". That violates one of the invariants of C objects. The defined interface of the class is broken. And that's a problem.

    Ooh, what have I started here !?

    So basically it's a way of forcing the base method to be invoked even if the immediate parent classes have over-ridden it.I guess this becomes a way of achieving partial inheritance - given my original inheritance tree, a class D can fall back to some methods from class C in the normal way, but if there are some cases where class D wants to make sure class A's method is run, then it implements the methof itself and uses a helper class B which uses this trick to call class A method directly on the class D instances.

    Of course it would probably have been easier just to reimplement the original behaviour in class D - except that this way the A class private data in the instance of class D can be used directly and the programmer of class D doesn't need to know the details of the class A implementation to access it. On the third hand, it makes my head hurt :unsure::unsure:

    • Like 1
  16. I'm far from an OOP expert so I may be way off base here, but that inheritance structure strikes me as odd. Class A is your GenericMeasurementObject and Class B is an array of GMOs. Doesn't that violate the "Class B is a Class A" rule of thumb for inheritance? What you're describing might work but I'm concerned your path will lead you off into the weeds (having spent much time there myself) with an application that is difficult to maintain or expand.

    No, that bit's ok - class B isn't an array of GMO's - it has private data that is an array of GMO's. Aristo Queue demonstrated this sort of an idea in the Map LVOOP example that will be buried somewhere in hte LAVA 1.0 content.

    The problem, I realised as I walked hom through the rain tonight is that (apart from living in a wet climate !) I was being terminally confused over what methods would execute when the call parent node ran - even if it had worked on the basis of the dynamic despatch class inputs rather than the owning VI's class, it wouldn't have done the correct thing for me. Also consider what would have happened if I really did have an instance of class A going into it - what method would have run ? That's not saying that the original question was stupid - it's not obvious how call parent method node determines what the parent is, and it would probably be a good idea if the compiler required the dynamic despatch marker in the class wire to enusre people like me don't write crazy code.

  17. Wow. I think you've created a situation I never expected anyone to construct. The answer to your question is easy, but you make me think we ought to kill the functionality you're taking advantage of. And, more than what we (LV R&D) ought to do about it, I really want to know why the heck you are in this situation!

    Ok, just so that you get some idea of how the thought processes of your users go....

    My program is measuring a widget as a function of temperature, magnetic field, voltage applied to device etc. All of these measurements essentially follow a pattern of construct a list of temperature or whatever, iterate through them one by one, measure widget, save data repeat until done.

    So I write a base class (A.lvclass) that knows about constructing a list of values, initialising somehing, iterating to the next value, working out when all the measurements are done and a whole bund of other things. I then implement each type of measurement (magnetic field, temperature, applied voltage whatever) as a subclass of A - these are classes C,D,E etc. All is fine in the world and my students give me data.

    Then my students come and say "ok, this is fine, but I want to measure over both field and temperature". So I think, I could just expand my program to work with 2 instances of class A separately, but somebody is bound to ask to iterate over 3 parameters, so instead the cunning way to do this to make a new descendent class of A (B.lvclass) that takes an array of child classes of A and for each method simply calls the corresponding method for each element in my array of class A. Since dynamic despatch works, I'll call the correct method for whatever class is actually stored in my array. So I'm doing the second version of your list of operations below.

    Now I get lazy - I'm essentially writing the same block diagram for each and every method class B - viz, get array of class A, index through it, calling methods, stuffing the elements of the array of class A back into the array and thence back into class B's private data. So being lazy I wonder if I can just keep doing Save As for each method having used the call parent method node so that it automatically picks the correct method.

    Then I realise that I'm not a 100% sure what call parent node does in this circumstance. :frusty:

    Short answer: The Call Parent Method always calls the ancestor implementation of the VI. It does not care about the type of the object on the wire. So Call Parent Method on the block diagram of B:M.vi will always call A:M.vi.

    Long answer: Somehow you have an instance of D on a diagram of B:M.vi and you are passing that D object to the Call Parent Method node. How did you get this instance of D on the diagram of B:M.vi? Here is how I would have expected that it got there:

    1. Top level VI is "Caller.vi"
    2. Caller.vi has an instance of D on its diagram
    3. Caller.vi makes a dynamic dispatch call to M.vi, which dispatches to D:M.vi.
    4. D:M.vi uses the Call Parent Method to invoke C:M.vi.
    5. C:M.vi uses the Call Parent Method to invoke B:M.vi.
    6. And now you are asking what the behavior will be when B:M.vi uses Call Parent Method, and the answer is A:M.vi.

    Now, that's what I would have expected. Your question implies that something like this happened:

    1. Top level VI is "Caller.vi"
    2. Caller.vi has an instance of B on its diagram.
    3. Caller.vi makes a dynamic dispatch call to M.vi, which dispatches to B:M.vi.
    4. On the diagram of B:M.vi, you somehow obtain an object of type D, either from a diagram constant directly on the diagram or retrieving this D object from some data store (global variable, queue, etc, or maybe just by unbundling data stored in the B object).
    5. And now you propose to wire that D object to the Call Parent Method.

    Please tell me that is NOT what you are doing. It sounds like it is, but it shouldn't be happening. There should never be a reason why you would ever want to do this. If you directly pass that D to the Call Parent Method, you are destroying the data integrity of your D object. Any object assumes that if it provides an override of any method then the ancestor method will never act on that object unless it was because the overriding VI used the Call Parent Method to invoke it.

    I and my team never discussed this case. The fix for the LV compiler is obvious and easy -- the dynamic dispatch input terminal of the Call Parent Method should only accept wires that propagate down from the dynamic dispatch input of the invoking VI. In other words, only the wires that have the gray background should be able to wire to the dynamic dispatch input of the Call Parent Method, and the VI should be broken if anything else is wired. That is not enforced today, mostly because it never occurred to anyone that you might ever try something like this.

    I could be completely off base in my understanding of what you're asking. But if I've hit the nail on the head, can you please explain *why* you are passing this D object to the Call Parent Method without climbing up through the hierarchy, starting at D:M.vi? If there's a real-world use case for this, I am going to be absolutely stunned. My bet is that you're just creating a situation in which D is not being updated correctly.

    Now, it is legit to have this situation (steps 1 to 4 are identical to the previous steps):

    1. Top level VI is "Caller.vi"
    2. Caller.vi has an instance of B on its diagram.
    3. Caller.vi makes a dynamic dispatch call to M.vi, which dispatches to B:M.vi.
    4. On the diagram of B:M.vi, you somehow obtain an object of type D, either from a diagram constant directly on the diagram or retrieving this D object from some data store (global variable, queue, etc, or maybe just by unbundling data stored in the B object).
    5. You make a new dynamic dispatch call to M.vi, passing the D object as the dynamic dispatch input. This will call out to D:M.vi and may eventually make a recursive call into B:M.vi, if all of the override VIs keep invoking the Call Parent Method. This eventually results in a recursive call to B:M.vi, which will either panic stop if the VI is not reentrant or will allow the recursion if the VI is reentrant. You'd need in that case to make sure that B:M.vi is written such that infinite recursion does not occur.

    Does this sound more like what you're intending to write?

    Yes - basically I was just being lazy ! Still, at least I've learnt something interesting even if it does mean I have to go back through my class replacing all of the call parent nodes with the correct specific method. Although your comments about reentrancy do remind me I ought to put a test to make sure than I'm never actually have an element of class B or a descendent of it in my array of class A.

  18. I thought I understood how dynamic despatch worked and calling parent methods within a dynamic dispatch worked, but now I'm having second thoughts :o ...

    Suppose I have a class hierarchy like this:

    A.lvclass |----B.lvclass |---C.lvclass        |--D.lvclass        |--E.lvclass

    Now B.lvclass has private data that is of type A.lvclass. And all classes have a dynamic-despatch method M

    Now in a particular wire of B.lvclass, the private data contains an instance of D.lvclass

    B.lvclass:M invokes Call Parent Method on it's private data (which is an instance of D, but with control type A). What version of M is run ?

    Is it A.lvclass:M since that is parent method of B.lclass:M (which is what I would expect), or is it C.lvclass:M which is the parent method D.lvclass:M

    ie. does Call by Parent Method work out which class to execute by looking at the type on wire on its dynamic despatch terminals or by looking at the class of the calling vi ?

  19. It could be that the Cleanup Tool does not know the inplace structure. In this particular case the inplace structure is completely useless anyhow. A simple Replace Array Subset will do the same with no performance degradation of any kind I could think of.

    Further playing around suggests that there is some badness creeping into LV's compilation - copying and pasting the main error case structure to a new diagram can let me run the cleanup ok.

    You're quite right about the inplaceness structure - it's rapidly becoming my favourite inappropriately used LabVIEW structure :cool:

  20. This is a latent cross-post from the NI forums, but I figure that the LAVA readership has a higher density of real experts than the NI site.

    In the course of working the Scripting Tools library, I've manged to generate a block diagram that is obviously in need of some cleanup and for which, when I press Ctrl-U, the cleanup tool beeps at me and does nothing else.

    Can anyone shed any light on what code constructus might cause the BD cleanup tool to fail like this ?

    I've attached a screen shot of the vi in question - if you want to look at the code then just check out the current LAVACR svn repository (8.6.x folder) from http://code.google.com/lavacr

    The problem area is the in-place structure between the 2 tunnel property nodes (vi-scripters will recognise this as turning on case insensitive selection in a case structure).

    post-3951-124699182404_thumb.png

  21. Ok, this is probably me being stupid, but having had my CR entries repatriated (thanks !) I can't find the way to uploading a new version of the file and editing the meta data. The list of "My Files" in my profile has the correct entry but doesn't have an obvious (to me anyway :wacko: ) edit link, nor does going straight to the CR entry page. What have I missed ?

×
×
  • Create New...

Important Information

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