Jump to content

mje

Members
  • Posts

    1,068
  • Joined

  • Last visited

  • Days Won

    48

Everything posted by mje

  1. Well, I'm definitely not the resident expert, but we do use SQLite for our biggest LabVIEW application. Typing can be tricky since columns don't have a fixed type, it's the individual values that are typed. That said, SQLite pretty much interconverts as necessary, so doesn't really care about types in most cases. 1) Non-issue really. If you see a LabVIEW string, you'll always have to check for null characters anyways to decide if you're going to bind text/blob. Unless you store all text as blobs, but then you need to throw collation out the window (I think?) and searching becomes interesting. 2) U64s will store just fine as text, though searching might bet a bit weird. Keep in mind SQLite decides how to store something, not you. Even if you bind the string "123" as text, there's a good chance SQLite will store it as an I8 instead (though column affinities might come into play, not sure). 3) Eek, I wasn't aware of the NaN issue. Not a big deal though since null is meaningless to a DBL. If the user is requesting a DBL, do a type check: if you see a DBL, retrieve the data, if you see a null, return NaN. 4) For timestamps, I like the ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS") values. They're easy to read, easy to parse, easy to generate. I'd stay away from variants, due to performance hits. If you're set on them, leave them on a top level palette with lower level access.
  2. I was on Win7-64. I'll spin up my virtual machines on Monday and see if I can get under 50 px.
  3. Hmm, I stand corrected. The Tick Count (ms) primitive seems to be returning 1 ms increments to me. Has it always been like this? I swear I used to see granularity in the return value...
  4. The basic timing primitives and VIs that have timeouts function off a resolution set by the system timer which is controlled by the host operating system. Even on modern PCs, you'll at best get a system timer resolution between 10-20 ms. This is something LabVIEW inherits from the OS, I believe all non-deterministic operating systems have similar resolutions. I've done very little deterministic programming, and none of it in LabVIEW, but even then I was dealing with tick resolutions on a similar timescale. The reason the system timer is so coarse is largely beyond my comprehension, but as I've been told it more or less boils down to scheduling. Having the scheduler decide what to run is overhead, and chopping the timer resolution up into finer increments means your scheduling overhead runs more often, chewing up a larger fraction of your processing time that is best spent executing other things. All of that though has nothing to do with how fast a VI can run. You can get VIs to run in well under a millisecond. You probably won't get down to a microsecond though, there is some amount of overhead involved in a VI call (as is the case with function calls in any language). That doesn't mean you can't execute a chunk of code more often than a microsecond, careful placement of loops, use of inline VIs, and subroutines can make for some pretty impressive speeds. However to get meaningful metrics off pieces of code like that you need to loop such that you execute however many times to get an appreciable amount of time passing, then divide the elapsed time by the number of iterations.
  5. Ton's example still enforces a 50px minimum size for me. I've run into this as well, one of my application's has floating windows which appear as context information when the mouse moves over other VI panels, and I've not been able to size them smaller than 50px in either dimension.
  6. I've been following this thread wondering what it is about VITs that would make them desirable to use over reentrancy, but didn't want to derail it. I think AQ just answered question: nothing.
  7. Indeed, and SQLite is an excellent lightweight database.
  8. mje

    CS Grammar

    Nice. I had no idea there was a built in optimized index for that in SQLite. That should be very interesting to explore...
  9. mje

    CS Grammar

    Thanks Phillip! That quadtree is pretty much what I imagined in a 2D space. New words are fun! What I'm really after I imagine is simply extending a binary search into N-dimensions, but the fact that's I'm dealing with areas, volumes, or N-dimensional volumes does add a slight kink. That seems like a good start.
  10. mje

    CS Grammar

    Hi Gang, I need some help with some computer science grammar. Say I have a 2D surface and an array of rectangles in that geometry. For an arbitrary coordinate I need to determine which rectangle, if any, contains the coordinate. I have a simple solution that just tackles it via brute force, and it works just fine because I typically don't have to track more than a thousand features. However I think this is a good learning experience. I imagine how one can do much better than iterating over each element by building a branching data structure and stepping through the hierarchy. I know this is a common problem in math and CS but I have no idea what this is called, so I'm not having much luck with blind searching. Does anyone at least know the name of what it is I'm trying to do?
  11. Is that what's happening? Oh man, that cursor switching was driving me crazy but could never correlate it with a cause.
  12. That's interesting. Though both my xcontrol and native ui tests now render reasonably quickly now, the xcontrol is considerably laggier. I wonder if it's the two UI queues competing for processing. Might be best if I stick with the devil I know...
  13. Ah, found a flaw in both my test and the xcontrol. Basically, the xcontrol was hanging onto the raw picture data, which is a bunch of non-rendered opcodes. The test was using a pre-rendered bitmap. It seems moving an image around is far more efficient if it's a "flat" bitmap. Add in this little ditty before dumping the image into the picture control and things work quite well. Ok, I'm back on the XControl bandwagon.
  14. I took my first plunge into XControls a while ago with a proof of principle of some functionality I'd like to implement in one of my applications, and I'm curious to hear from those of you who have more experience with them than I. My XControl is basically a single 2D Picture, with a some rendering logic attached to it. In the end, it generates a decent size image (usually in the neighborhood of 5-10 MP), and has tracking logic to translate location to rendered features. Obviously I'm only showing a subset of the image at any one time. I found the easiest way to do so is just to play with the Picture.Origin properties of the control, or alternatively just show the picture's scrollbars. The problem is both of these are hideously slow in the XControl, when operating on the picture I'm lucky to get more than 2 or 3 frames per second. In another test, I borrowed the rendering logic of my XControl, and used it to render into a picture control in a normal VI, then tried handling the same mouse tracking algorithms in the VI's own loop+event structure and it works pretty slick, moving the picture around is very smooth. So the question is, is there something about an XControl implementation that is fundamentally slower than just kludging together all the pieces in a "normal" VI? I really like the XControl encapsulation, but if it comes at the expense of performance, I'll take kludgy over encapsulated any day. I keep looking at the XControl trying to find something that will slow things down, but I admittedly still don't really understand what's going on under the hood of XControls, so I think I'm fighting a loosing battle on that front. Sorry, I can't post the XControl logic. I'm just curious what others experiences are.
  15. Nope, just thought I'd post it here. Not exactly a critical bug since it can easily be worked around. I have a few other counter devices I wish to test it on, then might file a ticket with NI.
  16. I think it's quite well documented. Note the referenced link in the quote. Also relevant is the KB article Configuring the CLFN, which describes using wildcards, and a few other nuggets.
  17. This one caused me a day of grief. Turns out an error in the start up logic of one of my applications would request a duty cycle of NaN to a counter output I'm using for pulse width modulation. The problem is the NaN request goes through without returning an error. But the next request to update the duty cycle hangs the DAQmx write VI. After hanging, there's no way out, aborting the calling VI leaves LabVIEW in a sorry state. Example: WARNING: Running the snippet above can leave LabVIEW in an undefined state. Save your work before you do so! Now obviously a NaN duty cycle makes no sense, but I'd expect DAQmx to be able to handle such requests gracefully, either by ignoring them, or preferably issuing an error. I've observed this behavior on the USB-6343 device.
  18. Gotcha, that makes sense. I actually see an error in my post, I was trying to say I expect the alternatives to be containment. All these silly semantics. Aggregation and containment are different forms of composition. I trip over these words all the time. Anyways, to me what you describe is containment, because the Engine becomes attached to a Car, and once attached is only accessible through the Car. I completely agree though that the line gets blurry, because you definitely can have an Engine before you have the Car, and it could also be removed, or returned when you're done with the car...
  19. Also somehow missed this discussion the first time around. I don't understand how an aggregation model can ever be implemented purely by value. The very fact that you're aggregating something with a lifetime independent of the aggregator means the items being aggregated are exposed and potentially likely used outside of the scope of the aggregator. If these objects are operated on in an external scope and you're aggregating by-value, how would the aggregated values ever possibly contain accurate state information? The aggregator model to me requires some level of referencing mechanism, be it DVRs or otherwise. If anyone can generate an example illustrating otherwise I'd love to see it, but I suspect such examples would actually be composition (where the lifetime of the contained objects is tied to the container).
  20. The closest I think you can come is using nested subpanels. Top level VI is simply one with two subpanels. It hosts one of your dynamic UIs in one and a clone of itself in the other, which in turn hosts another UI and another clone. Keep going until done. You then would need to manage the scrollbar on the top level VI, along with the size of all the nested panels. In theory doable, but very messy. I have an app I'd like to do this in, bit the kludginess of it all has turned me off even trying. The good news is that this should be doable in a fairly extensible way, but I agree dynamic control creation would be way better.
  21. Other than the obvious changes in interface, I really don't see the difference because in the end they are functionally equivalent: there exists some means of unregistering. Between these two options, I prefer an separate unregister method because it's more explicit. I know you said you're working entirely by value, but the unregister method is also somewhat consistent with the acquire/use/release paradigm that is all over the place in LabVIEW, even if that is usually for reference objects. Now of course I can't really say if an unregister method is required. That's something that's on you. I imagine you're entertaining the idea though because you can imagine at least one use case where it would be useful...
  22. Can't say I know the hardware, but I just finished an application that had to do much the same, only I was doing an SPI read rather than an counter read after a digital edge is received. All I can say is I had zero luck with any form of digital edge detection in DAQmx (the mode where you set up an event structure to get signaled upon a digital edge transition). Everything seemed to work as no errors would ever be generated, but nothing would ever cause my blocked code to wake up. The example VI didn't work either. I'd watch the pulses go by on my scope, meanwhile the DAQmx driver was on a coffee break or something. I know the mode works though, as I have used them in the past, all I can say is there seems to be something going on where some hardware just silently refuses to work in this mode. This was on an X-series USB device for what it's worth. I could poll the line and things would work... Ultimately I ended up configuring the digital line as a clock source for a timed event structure and I do the read when the loop wakes up. No idea why the digital edge can be detected as a clock source but not a digital edge. Maybe it's just not...edgy enough? One of those mysteries of the NI universe I guess. /shrug
  23. It is very important to realize the cast or flatten primitives do not provide you with the binary form of the data as represented in memory. They do provide you with a serial form of the data which can be used to rebuild the data. It's an important distinction. When passing variable length data into DLLs, break them out of any struct/clusters. Fixed length clusters are fine, so long as you're mindful of byte boundaries/padding (#pragma pack(), etc). For arrays and such, pass in two items, an integer specifying the length, then the actual array as an array data pointer. For example: This code calls a DLL to generate 3 arrays of data all of equal size. It first initializes three dummy arrays at a known maximum size, then passes the arrays, along with their size to the DLL, which populates the arrays with data. The DLL knows not to exceed the given size, and returns the actual number of elements used, so LabVIEW then trims the arrays if needed after the DLL call. The other way of doing it is to make two serial calls to a DLL, one to determine the size of the arrays you'll need, LabVIEW then initializes the arrays, then call the DLL again by supplying the appropriate sized array. Which to use really depends on where your bottleneck is.
  24. Maybe that instability is after the slug went through the concrete wall?
×
×
  • Create New...

Important Information

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