Jump to content

gb119

Members
  • Posts

    317
  • Joined

  • Last visited

  • Days Won

    7

Posts posted by gb119

  1. QUOTE(Paul_at_Lowell @ Jul 19 2007, 06:17 PM)

    OK, well, I tried to put all this together. I attached a solution (not fully tested for all cases). I created this within a class library but you can remove the "ArrayOfObject in/out" without harm. I added some comments to Gavin's underlying code (which is the important part) so that with luck maybe even someone like me can understand it. :)

    Uhhh, doesn't the application instance id always end up being set to the FF FF FF FF special value in your version ?

    Commenting code is a good thing, I probably should do more of it... :)

  2. QUOTE(Paul_at_Lowell @ Jul 19 2007, 05:01 PM)

    My search algorithm works fine now but there is the minor issue--well, minor for my purposes--that one can wire pretty much anything to it (although Gavin's code will filter this at run-time) since I left the input as variant (and array of variant). Is there a "LabVIEW object" type that I can use here? Hmmm....Gavin, I see you have an object called "LV Class In" on your diagram. Is this a specific class or did you find a generic class? If so, where did you get it? I don't see such a thing....

    Yes, you can have a Labview Object control, the reason I used a variant was to do with how the coercion works and the need to get a application instance ID.

    The application instance ID is only in the type descriptor array not in the flattened string data. Now, if you make that input a LabVIEW Object control, then when you wire up your class control it will be cast to a LabVIEW Object first. Then you flatten that to a string, and recover the 'real' class name from the flattened string, but the type descriptor array refers to the wire type which is a LabVIEW Object and not a wire of your specific class. The problem is that the application instance (which is derived from the type descriptor array) for a LabVIEW Object is always FF FF. Therefore, although you get the correct class name you don't get the correct application instance id.

    With the variant input, your 'real' class type is wrapped up in the variant, so when you flatten that to a string with a type descriptor array (using the flatten variant function) you get the type descriptor of your 'real' class with the real application instance id. The flip side is that you need to check that you are really looking at a Class and not at anything else which is why I have that little bit of error checking code first.

    The best solution would be to wrap the class name finder up in an XNode which could do the check to make sure it was being fed a class at edit time, but I thought that was probably complicating matters a bit too much for a quick and dirty hacked solution. If I get keen I'll write the XNode and release it via the code repository (if nobody else does it first).

    Oh and the random LabVIEW Object constant on my block diagram was a left over from a previous iteration of the code :rolleyes:

  3. QUOTE(tcplomp @ Jul 19 2007, 11:49 AM)

    I was using the Xnodes from the CR ;)

    That might be the source of the error.

    Ton

    I'm guessing this might be my XNodes then. There are problems if the linkages for all the ability vi's aren't quite right. Try to mass compile the folder with the .xnodes and their ability vi's in and see if that claims to be missing any vis.

  4. QUOTE(Neville D @ Jul 18 2007, 08:33 PM)

    I'm pretty sure that you can't use property nodes (or attribute nodes as they were called in LabVIEW 5) because I seem to recall that the Value property came with property nodes in LV6...

    Unless I'm missing something, the question is actually how to set the value of the 4 ring controls in the sub-vi based on the first 4 selected values of the list control in the parent. The way to do this is to have a hidden array control of integers (I think you can hide controls in LV5 by right clicking on them in the block diagram) that is connected to the connector pane of the MultiPlot sub-vi. Have the ring control in LiveDAS wired to this array input on Multiplot, then in Multiplot before you start doing anything else index elements 0-3 of the hidden array and feed those numbers into local vairable nodes (structures palette) for the 4 ring controls. Local variable nodes let you read/write to control or indicators irrespective of whether they are controls or indicators. They're very useful for exactly this sort of problem of sorting out initial values in a user interface, but are also very easy to abuse. Be very very careful when writing to a local variable and reading back from the control that you make sure that order of the write and read is deterinistic - i.e. controlled by data flow, otherwise you get all sorts of horrible race conditions. These typically come and bite you when you change something in the code or hardware that marginally changes the execution timings.

  5. QUOTE(Paul_at_Lowell @ Jul 18 2007, 05:19 PM)

    Well, there is another topic on this board (http://forums.lavag.org/Finding-out-LabVOOP-object-runtime-class-t5220.html' target="_blank">http://forums.lavag.org/Finding-out-LabVOO...lass-t5220.html) that in part describes the class coding and the differences between the root LabVIEW Object class and developer-created classes. I'm not sure there's quite enough information there to figure out how to do the comparison reliably (not just by class name, but perhaps application instance and certainly by namespace as well).

    Ahhh, I'm reinventing the wheel.... actually that thread provides a lot of useful information. I've edited my original post with a new version of my class namer tool that extracts more information from the class reference and (I think) now includes enough to properly test the class identity. Although I coded from the information in the thread, it's actually very similar to the OpenG Object template version except mine handles the special case of the base class which the OpenG oibject template don't have to worry about.

    I'd now revise my wish list for the possibility to access the class heirarchy in the runtime so we could do whatever testing of class hiearchy that we wanted to. (Actually I notice that you can wire a LabVIEW class to a property node - it would be very cool if we could expose the class hiearchy through the property nodes - it would be even cooler if we could write custom properties like in XControls - it would be a nice way of creating pseudo public/protected data instead of get/set methods.)

  6. Dunno if it's too late now, but here's a couple of XControls I've been playing around with.

    http://forums.lavag.org/index.php?act=attach&type=post&id=6393

    One is a signal generator XControl that produces a waveform output, second is a simple toolbar XControl that will return a cluster with the index of the button last pressed and whether it was a transitory click or a latch/unlatch type event.

    © University of Leeds 2007, released under the BSD License

    I'm considering submitting the toolbar to the CR unless someone puts a better implementation there first :rolleyes:

  7. QUOTE(Paul_at_Lowell @ Jul 17 2007, 05:54 PM)

    How can I programmatically compare objects (without comparing the object data)?

    In my case I have one class in which I initialize a number of objects and insert these into an array. The array is of type "Parameter" class and the elements are objects corresponding to child classes of "Parameter" representing individual parameters (e.g., AirTemperature, BarometricPressure, etc.). This allows me to autoindex the array in a for loop when I want to run a common method (well, usually with dynamic override methods) for each parameter.

    Sometimes, however, I need to retrieve a specific parameter from the array. I tried using an object constant as the search element input in "Search 1D Array" and this works if I have not initialized or otherwise altered the array objects. If, on the other hand, I have initialized the objects or otherwise changed the data in the objects the comparison method within "Search 1D Array" does not find a match. (The comparison method doesn't compare what I want it to compare.)

    How do I compare objects without comparing their data?

    If I understand correctly you are trying to search for objects by class rather than by value ? You have an array of class A and are looking for which elements of that array are in fact class B objects where class B is one of a number of child classes of A ? You can use the "to a more specific class" node to test whether an object can be cast to a specific child class. You'd need to write your own set of search sub-vis though.

    (edit - oh the joys of fast answers - I see Omar Mussa beat me to it !)

    Another approach you could follow would be to have a dynamic method called e.g. Class_Name that returns a string containing the name of the class. You then override this in every child class, loop through your array of parameters calling Class_Name, do a regular search on the resultant array of strings and then index the array of objects to retrieve the specific class.

    One of my wishlist items would be a function in LV that returns the class name (or even better a reference) to the actual "on-the-wire" class.

  8. QUOTE(Aristos Queue @ Jul 10 2007, 08:12 PM)

    Addendum: I do really want to know how so many of us managed to use classes for 11 months after release before this got found. It hasn't even been reported from customers... my teammate found it randomly while working on something else. It amazes me sometimes just how long a seemingly common bug can go undetected.

    Ahhh, so it wasn't just me then. Actually it hadn't been a big enough problem for me to spend the time trying to work out why one of my classes always crashed when probed - I'd sort of assumed it was something to do with the class data structure, but I hadn't got as faw as working out some test cases. Good to know it'll be fixed...

  9. QUOTE(ntward @ Jul 7 2007, 10:17 AM)

    I need to make a control which is also an indicator (in the sense that it reflects it's output state as well as an input). I know I can customise standard controls, but I can't figure out how to do this. Any tips, pointers, suggested help topics etc. greatly appreciated.

    To explain more clearly: My control needs two states; on and off. When on, the control will open a valve (I've got all that sorted). A micro-switch measures the position of the valve. If the valve has failed to open (i.e. control output and input differ) then I want to indicate this by altering the background colour of the control.

    You probably want to look at property nodes for this - they're a way of programmatically changing the appearance of a control.

    Right click (or platform specific equivalent) on the cotrol (I'm assuming you're using a boolean here !) and select Create->Property Node and pick the property of the control you want to change. I'd suggest you look at colors (to change the colouring of the control) and probably disabled (to stop the user from trying to change the control if there is a malfunction).

    Other (more complicated) solutions would involve having a transparent control overlaying an indicator - the user operates the transparent control and you report report what is happening with the indicator - e.g. make the indicator a color box and use different colours to report valve open/closed/stuck open/stuck closed.

  10. QUOTE(LV Punk @ Jul 6 2007, 08:18 PM)

    Just a suggestion, but if the aim is to generate images of all possible block diagram objects, why not use vi scripting to generate each possible object one by one, then use the bounds property of the GObject class and the Block Diagram image method of the vi-class to get a flattened pixmap of the created BD object ? (A word of warning, I tried to do this quickly but keep crashing LabVIEW - I suspect it doesn't particularly like me trying to create and delete one of every possible object on the same BD in one run...)

    Edit: Ok - I've generated png for all the LV objects that I can do without LV crashing on me - here they are if someone wants to sort them into catagories (perhaps that can be done using the pallete menu api to work out which images belong where...)http://forums.lavag.org/index.php?act=attach&type=post&id=6325

  11. QUOTE(Guillaume Lessard @ Jul 5 2007, 11:45 PM)

    Hi,

    I'm working on a little messaging framework to send data over TCP between two machines. That's simple enough, and I thought I'd save myself a bit of work when sending complex data types by converting them to variants and then flattening the variants to strings.

    What I didn't realize is that "Variant to Flattened String" doesn't really flatten into a string, but into a string and an array of integers. That doesn't really help for sending data over TCP, unless I cluster that up, flatten the cluster and send that. Ick.

    [...]

    Assuming you don't care too much how verbose your TCP transmissions are, why not use the (un)flatten to/from XML functions ? They (obviously) don't use a type descriptor array and with the string data being human readable it might be easier to debug if the conversion failed...

  12. QUOTE(mdd100ai @ Jul 4 2007, 10:30 AM)

    If you are using LabVIEW 8.2 then my http://forums.lavag.org/downloads-file87.html' target="_blank">Scripting Tools toolkit has a polymorphic vi that returns a class constant of every possible type. This doesn't actually help you that much because in LV 8.x the properties and methods for scripting are hidden and can't be revelaed with any fancy ini file key.

    The Scripting Tools toolkit will create some nodes for you, but not a formula node (yet), but if you look at the Create Expression Node, you'll see that that is actually creating a formula node (and a mathscript node is a subclass of a formula). Alternatively, I'd reccomend the DataAct Class browser for those wanting to mess with LabVIEW scripting - I think it supports LV 7.x and upwards. It does cost $ if you want the version that can create property and method nodes.

    In terms of using a scripted vi in a project - firstly you need to be aware that it will only work in the development environment (scripting is really only for NI for writing development tools...). If that is not a problem, then what you will want to do is have a vi that creates and scripts a new vi that has the formula node, and then executes the new vi using the vi-server methods, before closing all the references to the new vi, hence removing it from memory.

  13. QUOTE(zoogies @ Jun 25 2007, 07:11 PM)

    <plug mode="own code">

    The http://forums.lavag.org/downloads-file87.html' target="_blank">Scripting Tools toolkit in the code repository has, as an example, a little program that can be put into your project folder that will find all wire references and run the clean-up wire method on them. The toolkit is LV 8.2, so if you're using 8.0 then it's not much use to you.

    </plug>

  14. QUOTE(Doon @ Jun 5 2007, 10:47 PM)

    Here's my solution.http://forums.lavag.org/index.php?act=attach&type=post&id=6040''>http://forums.lavag.org/index.php?act=attach&type=post&id=6040'>http://forums.lavag.org/index.php?act=attach&type=post&id=6040

    It uses the tab control simply as an enum. Personally, I would suggest using an enum. the values are shuffled into and out of the display cluster from the cluster array. Good points of this is that it only uses *one* cluster, ergo only one cluster to update. Bad points is the need to cycle data in-and-out of the cluster.

    Not wanting to be picky, but how do you adjust the number of tabs at runtime if the array size isn't 8 elements long ? That's the tricky bit.

    Perhaps one could make an array of booleans with a custom graphic on the button to make it look like a selected/deselected tab with transparent array housing with some logic to ensure only one element is true at any one time to simulate the tab strip and then usse the index of the true element to index into the array and use a single cluster control as in the above example.

    If platform independence can be sacrificed and the target is Win32 then I think the ActiveX tab control can have new tabs added at runtime - if so, that could provide the tabs part of the UI with a single cluster control displating the current index.

  15. QUOTE(Aristos Queue @ Jun 4 2007, 11:46 PM)

    I think you're thinking of a *while* loop.

    In a For Loop, since we know at the start how many elements will be needed, the output array can be allocated right away.

    With a while loop, it gets reallocated on each iteration to grow as needed.

    Does the while loop actually do the allocation on every iteration ? - I thought I'd read somewhere that it allocates in chunks of increasing size and then deallocates anything left over when the loop finishes. Did I totally dream that ?

    Is the compiler intelligent enough when looking at a loop to work out if the iterator terminal is unwired to not bother generating code to produce the iterator output, or would that explain why the array operation is faster ?

    On the original topic, what would be very handy would be if index array and friends took in a cluster of n-numerics to index a n-dimension array. Particularly handy for working with 2D arrays of images if one could wire in 'points' and 'bounds' type clusters to pull out points and subsets.

    Hmm, maybe my next XNode project :lightbulb:

  16. QUOTE(Eugen Graf @ May 30 2007, 09:38 PM)

    [...]

    QUOTE(Eugen Graf @ May 30 2007, 09:38 PM)

    Thank for your answer. I don't really know if I can use here Variant.llb. And I have
    LV
    8.0.

    Eugen

    So it looks like your data originates from outside LabVIEW - in which case I'm afraid there is no easy way - you need to convert your data to an array of unsigned ints (looks like your protocol aligns on 2 byte boundaries, so U16 will work) and with the individual elements. You can quite easily do U16->array booleans->cast to your type def.

    Here's an example of a U8 cast to an 8 element cluster of booleans.

    http://forums.lavag.org/index.php?act=attach&type=post&id=5973

  17. QUOTE(Eugen Graf @ May 30 2007, 07:35 PM)

    Hello, I would parse a boolean cluster but get some problems(Look attachment). Should I realy make a workaround with Cluster->Array or are there another ways to solve it?

    I want also interpret a boolean element as a boolean(=1 Bit) not as a Byte.

    Thank you, Eugen

    Flatten to string essentially gives you a straight memory dump of the data with (for versions < 8.0 by default and optionally for >=8.0) a separate ouptut that can describe the structure of the data. Sometime around LabVIEW 4.x/5.x the in-memory storage of a boolean was changed from one bit to one byte, so when you flatten a cluster of 8 booleans you do indeed get 8 bytes back. I'd hazard a guess that the change was done because RAM wasn't quite so critical and memory alignment issues were more so, so it made sense to reserve a whole byte even though only the lsb is used.

    I'm not entirely sure I understand what you are trying to do, but if you have 8.2.x or perhaps 8.x, then in the Utility folder of your vi.lib there will be a VariantDataType.llb which has subvis for interpreting variant data-types without getting your hands dirty looking at the flattened data.

  18. QUOTE(Darren @ May 23 2007, 08:00 PM)

    The feature I've been wanting that would be well-suited for one of these mythical "XNodes" would be a growable Array Size function, that returns 'n' scalar "dimension size" outputs, where 'n' is the number of dimensions of the array. I would much prefer this to the current method of dropping an Array Size and an Index Array.

    -D

    The feature that I have already implemented as an XNode returns takes an n-dimension array and a scalar x and returns the (x+1)'th dimension of the array or -1 if x<0 or x>n-1. Fairly elementary stuff, but I got tired of wiring array-dimension and then index array together. It hadn't occurred to me to make it growable - but then so far I've kept my XNodes nice and simple and just made non-resizable ones :-).

  19. As others have said there may be easier ways to do this, but to answer the original question...

    Flat sequences are a bit weird in the LV class heirarchy - you'd expect them to be Generic->GObject->Node->Structure->FlatSequence, but no the whole flat sequence structure is a direct descendent of GObject. That has a Frames property which gives references to a set of FlatSequenceFrame objects which is not even a GObject (!). That has a Diagram property which you can then use for the New VI object primitive for placing the tick count (ms) node.

    Not having tried to do this myself, I'd be interested how you are moving the body of the code into the middle frame of the sequence whilst leaving the terminal nodes outside and then rewiring it all up again.

  20. QUOTE(AdamRofer @ Mar 29 2007, 09:49 PM)

    The most I was able to do is get Node.Style to tell me it was an "Expression Node"

    Keep trying, though, and let us know! :thumbup:

    EDIT: It looks like the setup is almost identical to UnitCast (Convert Unit) objects, but the UnitCast.Unit property still doesn't yield the Expression Node stuff. Decoration.Text.Vertical Arrangement on UnitCast items is also not possible, oddly enough.

    Yup, it looks like it really truly is just a Node. I can't get a Text.Size to Text? to work either. On the other hand this whole typecasting of refnums so that property nodes don't notice you accessing non-exposed properties seems so completely and utterly hackery that I'm not sure whether to laugh or cry. I wonder if the NI employees enjoy watching us bang our heads against walls trying to do things that we're really really not supposed to do with LV :headbang:

  21. QUOTE(yen @ Mar 29 2007, 07:54 PM)

    I can't test this at the moment, but if I remember correctly, the class input does not determine anything. If this is correct, you can wire in the generic class and the enum will select the kind of node you're creating. Of course, that doesn't seem to make much sense (why else would you need to wire in the class?), so it's possible that I'm wrong, that this only works for some things or that this will be deprecated.

    The class input appears to define the Vi Server class of the refnum that comes out of the New VI Object which in turn determines which properties and methods you can access on whatever it is that you've created. As far as I can see, there must be a property or method to specify the expression that the expression node uses, hence one would expect the expression node to be some class different from e.g. the increment function. If one wires an class that is incompatible with the object that New VI Object tries to create then you get a type cast error (e.g. try specifying a terminal class constant while creating an add function). Compatible in this case means that the class you specify is either the same as the actual class of the object, or a superclass. The reason that wiring the generic class works, is that generic is a superclass of lots of things, but it does mean that you can't do very much with the object you've created without casting it to a more specific class first, for which you need the correct class constant... By replacing the generic control with more specific class types in turn, iterating over the class heirarchy and spotting which generate errors and which don't one can map out the specific heirarchy of the object that one is creating. Thus, I've got as far as 'Node' but no further.

    Actually, thinking about it, if I create an expression node on a block diagram, I wonder if I can interrogate that from another vi to determine the class type of all the nodes on the block diagram. Will go and try this...

  22. I'm playing around with scripting and trying to create an expression node (as in the in-wire formula nodes). I'm getting stuck as to what type of class to wire into the New VI Object primitive. I can tell that it must be some sort of Node class because if I use a Node class constant I don't get a type casting error from the New VI Object primitive. On the other hand it must be a sub-class of this because there needs to be some way to set the expression to be used. However none of the subclasses that the DataAct Class browser (great tool by the way for us trying to script in 8.20) knows about. Trying to create property nodes with class names set to likely looking strings isn't giving any joy yet either.

    Has anybody created an expression node through scripting, and if so, how do you set the expression ?

×
×
  • Create New...

Important Information

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