‎11-13-2012 03:01 PM
Hello,
So, I have a few possible solutions for my project, but am in the planning stages and would like to know what is the best solution for efficiency and quality of code based on the way that Labview is built.
I have many devices, temperature controllers, USB lab jacks, CAN busses to control sets of motors, ethernet controllers which control other machines, and even a few digital camears thrown in there.
The main essence of our measurement system is: set up a lot of paramters, and then collect data using the digital camears, do some processing, and then output the image files.
My goal is to set up a plugin system where I can essentially wrap the drivers for each one of these devices, and then create measurement sets using all of this equipment. Set up sweeps across any variable that is changable too.
In looking to do this, I plan to create a labview object which essentially can be used to wrap any of these drivers, and then use a plugin type system with many configuration files .ini settings to load all of the appropriate plugins and initialize and run the equipment.
However, I am running into an issue of design philosophy. When running these subsystem plugins, I never want any of them to be blocking. However, sometimes a measurement itself is blocking (camera dwell) etc. So I need subsystems which are always running and "taking the hit" of the blocking, and letting other parts of the program know when they are done.
Polling ideas:
So, I can send a "move" or "update" command to one, then poll it to check when it is done, and then "get data" to grab this data when it is done. This would require the object itself to have either shared variables or refnums to boolean and data, so that one (blocking) VI (called via invoke nodes) can be updating these when it can, and the unblocking vi to check these shared variables.
Using refnums more liberally:
In this scheme I would set it up such that the same refnum that is part of the object, can be grabbed, and then a dynamic event can be set up in the "main" program. This main program would wait until the "data ready" boolean changes, and then based on this event will grab the data.
Other options revolve around global varaibles and things I don't want to deal with, becuase this is suppsed to be a plugin style architecture so that nothing can block or interfere with eachother.
Also, when it comes to runnig these sub vis that are blocking and doing measurement, I want to minimize the CPU time and memory usage, such that I can do other processing at the same time. (Why I awnt it to be non blocking, so that many tasks, saving to hard drive, waiting for camera dwell, collecting statitics on temperature values) can be happening simultaniously.
I have also, in my planning stages, started to look more into the NI-DAQ style stuff. I had originally assumed that this was purely a set of tools that can be used with the NI hardware, but it looks like I could be able to set up virtual devices on this framework. I was also somewhat curious if these devices could take the place of this plugin style architecture I was planning on making.
I should mention that I am coding in LV2009 right now, though, if the design of this style project hinges on something in a newer one, I can imagine upgrading to a newer version of labview.
Thanks for any help and guidance
‎11-15-2012
05:27 PM
- last edited on
‎01-29-2025
09:09 PM
by
Content Cleaner
Hi jawaugh,
Since you want to collect data using your cameras, process them and output them. I pretty recommend you to take a look to Vision Module:
Best Regards,
Carmen C.
‎11-15-2012 05:47 PM
Thanks for the response, I have not looked into the vision module stuff at all, though I think that's a little separate from what I am looking to do.
So the images that we are capturing we have to process in various other vary non standard ways, for which I have a few analysis programs written in C, and plan to even make some that run on GPUs (and separately plan to manage the communication and processing overhead in that setup). So, in the end, I only need the 2D data from the camera. (we use monochrome, very fast cameras) The actual camera taking data and analysis part is of little bother to me at the moment. The main issue is how to do this efficiently, as we are working with very fast (up to 300 FPS 2 MP cameras).
I want to be able to, while sub VI systems are loading in these images as fast as they can keep up with (just into memory temporarily), and other VIs move the data away, set up processing programs (which I have made externally in C and such), return the data to labview, and then essentially add these images together and store the processed result (I only need to save the at most, 5 MB of data every second, which is well below the limits of the hard drives I have).
Main issue here is, I need this to run all in parallel. I can set up the camera to take sequential images, and even make a sub vi that sets up a buffer and fills it. But, how can I access this data in the best way from other VIs? Do I use shared variables? Or is the overhead too much to fight. Globals seem reasonable, but at the same time are messy since this is supposed to be a plugin framework. I was considering writing a refnum based event structure system, where I watch to see when data is available from another VI, to set up other subsystems to run on the data, etc. I have been having trouble finding out the best way to essetnailly properly handle this data passing concept with the least overhead and least access conflicts.
Also, somewhat separate, is this same program needs to be controlling many motors (various manufacturers), custom high precision high voltage controllers, misc usb hardware, some lakeshore temperature controllers, helium flow controllers, vacuum gagues and what not, logging these parameters at the same time.
Currently, I have working versions of all of the parts and everything together even, just not in a nice framework, and now I am looking to generalize the code, clean it up so that we can use plugins for all of these variables, and overall increase speed and reduce overhead of the measurement.
I feel like labview should be able to do this, but if not, I can always move back to coding everything in C/C++ and just use something simple for the GUI, and write my own wrappers for all of the equipment. I just was hoping to be able to use the labview code for various equipment and data movement / file management overhead, while the hard number crunching can still be separate. But, keep running into confusion mostly because of my mental blocks at being able to think in ... "labview" way I guess.
Any help is greatly appriciated~
‎11-16-2012
07:28 AM
- last edited on
‎01-29-2025
09:10 PM
by
Content Cleaner
Jawaugh,
Since you need to run all in parallel: Take sequencial images, buffer them, process them and output them, I recommended you to take a look a design pattern: Producer/Consumer Loop
Basically, this pattern consist in two loops: a "producer" and a "consumer". The producer enqueue the acquiring data into a buffer, and the consumer will dequeue the data. Please refer to this link:
Best Regards,
Carmen C.
‎11-16-2012
01:17 PM
- last edited on
‎01-29-2025
09:10 PM
by
Content Cleaner
Carmen,
Thanks for your response. This seems pretty close to what I need, I'm just worried about the overhead / functionality of it.
In terms of the queue structure, I'm looking to not let the queue build up in my application, simply because this needs to be running at maybe 250 MB/s data throughput continously for hours. And for this reason, if just for a few seconds a queue builds up, I will run out of memory. Also, I'm worried about the speed and efficiency of the malloc style commands that essentailly are happening non stop with this. Kind of curious about the overhead of the 2-3 MB allocations every 10 ms. Also, the dequeue element structure looks to be blocking, which is something I'm trying my best to avoid.
For this reason, I was leaning towards global variables, shared variables, or refnums to a spot in memory which the programs would work with.
I just now (in looking up stuff about the FIFO queues and producer/consumer style things) found Semaphores, which sound like the right way to maybe do shared memory properly. Is there an overhead associated with using them that means I should avoid it, or is it the right way to do what I'm looking for? https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z000000kFGkSAM&l=en-US
Thanks!
‎11-16-2012 03:52 PM
Actually, you can specify the maximum number of elements you want the queue to hold. If a queue reaches max queue size, the Enqueue Element waits until the Dequeue Element function remove elements from the queue.
In the other hand, using semaphores is a good choice to avoid race conditions in case that you're goint to use share variables or global variables.
Have a great weekend.
Carmen C.