From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.
We appreciate your patience as we improve our online experience.
From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.
We appreciate your patience as we improve our online experience.
Author: Elijah Kerry, CLA
Last update: May 19th, 2018 (NIWeek 2018)
Overview of the Measurement Abstraction Framework
The attached code serves as a reference architecture for the core architecture of large-scale test and measurement systems, especially long-running tests that are commonly associated with the characterization and validation of a physical system.
The Measurement Abstraction Framework demonstrates solutions that address the following common requirements:
Example Overview
Version 5.0 has been used to build an EV Powertrain Validation test demonstration, which will appear on the Expo floor of NIWeek, as well as various locations around then world. The attached code includes the device plugins that were used for this particular application. Once installed, it can be run, but will almost certainly generate an error unless you happen to have the same hardware at your disposal. The primary reason these were included is to serve as helpful examples for how driver plugins should be written.
To run the example without hardware, we recommend simulating one or more DAQ devices for use with the Standard Measurement.
Setup and Installation
Extending or Customizing Measurements
The example measurement is installed by default to C:\ProgramData\Measurements
The included example only features one measurement, "Standard Measurement," which his a very basic implementation. However, it is possible to instantiate N instances of this type of measurement, which should cover most basic use-cases.
Reasons to override this measurement include:
Extending or Customizing Hardware
The example measurement is installed by default to C:\ProgramData\Hardware
Unlike previous versions, all devices inherit directly from the base Hardware.lvclass object. The measurement device implements the acquisition and generation interfaces. Device plugins wrap specific drivers and are called used a basic "Configure --> Acquire --> Generate --> Measure --> Repeat until Close" sequence. A device can specify specific interfaces that they implement if requested by the framework, but the default is for a device to support "all" interfaces.
All devices have both common and unique configuration options. The common capabilities are stored in the base "HW Configuration.lvclass," but extended by their own implementation for unique properties
Future Updates / Known Issues
Additional Information
The following articles describe core design decisions of the original framework:
This framework is not officially supported by NI, but will continue to be improved and developed based on input and feedback. The original version of this framework was published in 2012.
Hi Elijah,
I got the files, thanks!
But I am still having some troble. After I open the Test Step.lvproj inside the MAL folder with labview 2012, some dependencies are missing. The following files are being asked:
1-Set Predefined Measurements.vi
2-BP Results.lvclass
3-Set Default Display Properties.vi
Could you put a complete version of the example available for download?
thanks!
Thanks. Must have missed your post re 2012 AF.
Is "Measurement Utility Script.docx" still in the works or where I can find it?
Still in the works. I have a new version of all this that I plan/hope to release soon. I'm currently OOO, but I will be returning shortly.
FYI - just posted a much improved version that includes build specifications for deployment
I've written a lengthy description of this application and my design decisions here: Designing a LabVIEW Measurement System with Multiple Abstraction Layers
I have a question about error handling in Controller.lvclass. HandleError.vi is overridden by Controller to call Receive Error From System, which sends a the message Handle System Error to the Error Handler Actor. The Handle System Error message in turn sends a Log Status message back to the controller with the error info. I see that the override of Controller:Handle Error has a TRUE constant wired to the stop actor? indicator, which will stop the controller's Actor Core, as I understand it. How can the Log Status message be processed by the controller, if the controller's Actor Core has stopped? What am I missing here?
Thanks
dirtyray:
Eli has been traveling a lot, and as this is his design, he'll have a more definative answer. I *believe* the answer is as follows:
I believe that the Error Handler Actor is designed to work with any caller, and so it sends messages back to its caller in the even that the caller is still running. In this particular case, the caller has decided to go ahead and exit. That does not negate the utility of the design of Error Handler Actor for other actors.
... but if Eli contradicts me later, accept his answer.
Ah, this is a very good question, and one I admittedly don't have the greatest answer for - in fact, this has given me pause to re-evaluate my error handling strategy in this system. Stephen's answer on my behalf is accurate, but that doesn't mean this is necessarily as it should be. The simple answer to your question is, "it can't be processed by the controller!"
Thinking back, I was torn between giving all the actors access to the error handler actor queue, or continuing to insist on decoupling everything, such that only the controller is aware of how to communicate with separate entities. As it stands, actors are designed to pass any errors to the controller, who then immediately relays them on to the error handling actor. Most of the actors just shut down if they incur an error, so if the source of the error happens to be the controller, it will shut down and never receive the log message.
If/when I re-approach this aspect of the design, I'm tempted to treat the error actor as a proxy for the controller in the event of an error - perhaps I would even include it in the controller library. I could give all the other actors in the system the error actor's reference in order to enable direct communication, and then encapsulate the decision making process within the error actor , who could then dispatch 'shutdown' commands via the controller, if necessary.
Not sure though... need to give this more thought...
gah! Found a problem. Removing the download temporarily - feel free to get a previous copy from an older revision if you like in the meantime.
Update: fixed! New version with error handling available for download (*.vipc file)
Elijah -
I'm highly intrigued by your framework and am using it as a way to "learn" the AF for an application I am building. You provide a level of complexity that's useful compared to the example projects provided with AF.
A question about implementation: is there a fundamental reason why you handle actor initialization routines in the Measurement Framework through messages rather than overriding Pre Launch Init? I saw a discussion here: https://decibel.ni.com/content/message/32630 where it seemed like Pre Launch Init was a way to contractually guarantee that appropriate initialization was handled. This seems crucial to me in hardware configuration, since the hardware device won't work properly if the actor gets launched without the appropriate setup. Thoughts?
I ran the vipc and it installed the measruement utility on my functions palette but Im not sure where to find an example project that puts it all together. I searched the example finder and the project templates available from the getting started window but didn't see anything. The Test Step.lvproj file in the C:\Program Files\National Instruments\LabVIEW 2012\ProjectTemplates\Source\Framework directory doesn't appear to be a coherent project either. Am I missing something?
David - click on 'Create Project' from the getting started window and you should see a new category, 'Demonstrations,' which include the Framework and a template for a new measurement. For more info on this and how it works, visit this link
Elijah -
I'm highly intrigued by your framework and am using it as a way to "learn" the AF for an application I am building. You provide a level of complexity that's useful compared to the example projects provided with AF.
A question about implementation: is there a fundamental reason why you handle actor initialization routines in the Measurement Framework through messages rather than overriding Pre Launch Init? I saw a discussion here: https://decibel.ni.com/content/message/32630 where it seemed like Pre Launch Init was a way to contractually guarantee that appropriate initialization was handled. This seems crucial to me in hardware configuration, since the hardware device won't work properly if the actor gets launched without the appropriate setup. Thoughts?
PS. Apologies for the repost, but I saw you answer David-A's question and realized I never got an answer to mine.
No worries! I actually dug into this a little after you asked it originally, but never got around to reposting - thanks for the reminder. Thinking back, I think my design decision was made at a time that the AF didn't contain a Pre Launch init. I actually went as far as attempting to move the initialize method into the Pre init, but experienced some odd behavior that I never quite debugged. So for now, the answer is simply that it was originally written against a version of AF that didn't offer this as an option and refactoring it would require time investment - one I'm willing to make, but just haven't yet.
When I compile a modified version of the Measurement Utility (additional measurement and hardware classes), the installed executable hangs in main.vi because it cannot find "Measurement Actor.lvlib:Acquire Continuously Msg.lvclass", (and its methods: Send Acquire Continously.vi, Send Data Update to Controller Message.vi). While debugging, I can point the application to the source files and get past the stall. I thought the problem might be in the "Additional Exclusions" settings of the Build Specification, but no combination of options seems to avoid the problem. Any suggestions for why this problem is occuring?
It successfully compiles without the modification though, right? Is it just the additional measurement that causes problems? In other words, if you just load the new hardware class - does it work? Could you post the measurement you created? Admittedly, the continuous acquisition method is new to the latest version... so some bug may have slipped throug the cracks.
On a hunch, I removed Strain.lvlib from the project (and zipped the folder in /Measurements)--since it is the only stock example that uses the new feature. Once I changed the Measurement.ini [Options] Load_{Msmts|HW}_From_Public_App_Data_Folder to TRUE, the installed executable ran fine. Running the EXE also ran fine (although it duplicated Measurements and Hardware from the Public Data folder, duh).
I put Strain.lvlib back into the project and recreated the missing "AcquireContinuouslyMsg.lvclass" errors.
This was on a relatively "clean" install of Measurement Utility v1.4.0.44 (although I made some changes to the Build Specifications).
Thinking I was on to something, I removed Strain.lvlib from my modified project and uncovered some missing files from my own code, but that is for another day.
Thanks for doing some troubleshooting on this for me. I'll dig into it tomorrow and see if I can reproduce it
Sorry for the delay - part of the reason I haven't posted an update regarding this question is that I've moved the code over to 2013 - I'll be posting a new version around NIWeek once LabVIEW 2013 has been released.
Anyway, I believe the fix to your problem is relatively simple. Check to make sure the re-entrancy of the acquire method is the same across the hierarchy. At some point, I think I changed the re-entrancy for the continuous acquisition method so that multiple instances of a strain measurement would execute as you would expect. Similarly, I should set all the dynamic methods of the measurements to be re-entrant.
I think the problem you've run into is that the re-entrancy is different for that method from the parent, which is not allowed. Try changing it and clicking the box to make them all the same and see if that doens't fix it.
A wonderful talk! I had viewed the slides, but hearing you present filled in a lot of the "missing pieces" and made the use of OO and Actors much clearer. Thanks for taking the time and effort to create this presentation.
Thank you! If you happen to be in attendance on the Monday of NIWeek (aka 'Alliance Day'), I'll be giving my latest presentation on it there. For those of you who can't make it, I believe I may also be presenting at various NIDays.
In case anyone is interested, I will be releasing the latest version of this example shortly after 2013 launches (yes, it will be compiled for the new version). I've revisited error handling based on feedback from this group and added much more doucmentation. I'm also working on an alternative controller to illustrate how it could be used headlessly.
Eli, I'd love to attend your presentation on Alliance Day but I don't see it listed anywhere in the NIWeek'13 scheduling app when I filter by day (Monday.). Do you know if it will be put there in the near future?
I believe the Alliance Day sessions are posted on ni.com/allianceday.
This particular session will be Monday morning at 10:00 am in 17B.
If you do a search by Track->Alliance Day, you will find the session.
Elijah,
I will be there on Monday (registered for Academic Day). Is it possible to "sneak in" to your session with this registration? [I recall last year a guard stopping those of us registered for a "Build Your Own" session because we didn't have an "Alliance Day" ribbon -- weren't you the one who got us past this block?].
BS
This is an unfortunate conundrum, and I would deifnitely get in trouble if I started systematically sneaking people in 🙂
If you can't make it, I do hope/plan to give this presentation at the regional NIDays this fall...
I just posted a brand-new version, so I'm eager to hear what everyone thinks! Time to finally take a break....
Enjoy!
3.1 Beta is now up, which now includes working build specifications for executables and installers for the controller(s), plugins, and in the template project.
I also decided to add a new feature in this release: a configuration dialog that enables modification of the system configuration while running (in both the server and client controllers). Now, I'll concede that adding features is not what a developer should be doing between Alpha and Beta, but.... hey, this system exists to illustrate how to solve hard and relevant problems! Enjoy...
For any TestStand users out there, I just posted a new controller that is designed for integration with TestStand here. It's an early proof-of-concept, but give it a look and let me know what you think! Note that it requires the latest version of the Meausrement Utility (posted today) to work correctly.
Eager to hear your thoughts!
Thank you 刘林! If you just downloaded it, I recommend grabbing the new version I posted yesterday - if you plan to dig into it, I think you'll find the code much more readable.
Some of you mentioned having a problem with the installer for Beta 3.0.1. Give 3.0.2 (uploaded this morning) a try.
Is there an old version that works with Labview 2012?
I'm afraid the last version that works in 2012 is quite old. With all the build tools I've created specifically for 2013, it would be non-trivial to release a package that installs in older versions. You might install it into 2013, create a project and then save for previous. I would expect this to work, but I haven't tested it.
You could also just upgrade to 2013 🙂
I think I might of somehow posted a question to the wron forum,, sorry if this is somehow a duplicate,, but here is the situation I have,,
I've read all the documentation I can find about LVOOP and the Actor Framework, this Measurement Utility looks great and I'm ready to "port" one of my simpler projects.
So I use the Project Wizard to build the new project, see that the main UI is the Server UI, I open it up but I can't seem to figure out how to add the old projects UI functionality, I must admit that this new UI architecture is a technique I have never used. So could someone point me to a document or example or whatever so I can get up to speed on this technique??
Thanks in advance.
I'm happy to help, but I'm afraid I don't quite understand the question. Are you trying to replace the Server's UI with a UI you created for a separate project? You can do this, you'll need to create a new actor class that is a sibling of the abstract UI class. This new UI definition will then need to be set as the UI the controller should use in 'Construct Controller.vi.'
If it's totally different, replace 'Measurement UI' with your new UI. If it's similar to the current Measurement UI you can inherit the functionality it contains (just like the server and client do now) and create a new child of 'Measurement UI'
This illustrates the function that sets the UI. Note that if you're new the AF, you might be better off starting with one of the current UIs and customizing it.
Also, the Server Controller is coupled to the Server UI. You'll probably want to create a new child class of 'Controller' and create a new 'UI' definition for that controller. This is similar to how the Server Controller is coupled to the Server UI and the Client Controller is coupled to the Client UI.
One final point: if you're looking for the actual front panel that appears, open 'Actor Core.vi' in the Server UI class. If you look at actor core of the parent class ('Measurement UI'), you'll see that it inherits a lof of the UI definition from the parent.
Hi,
I'm having problem creating a measurement actor (possibly due to dependency issue) and would like to see how you did it. Our company only has LV2012. If you can post an old version that work for LV2012, it will be great!
Thanks,
Joseph
ps. I did check your blog but still couldn't figure out what I did wrong...
What is the problem you have when you're trying to create a measurement actor? Are you using the template that installs with the package? If you've already been able to open it, you might just try saving for previous. I doubt I'll easily be able to create an installer for 2012 as I use automated build tools that are written specifically for 2013...
I have a question for anyone/everyone who has downloaded this system and put it to use: what industry are you in and what is the nature of the application you're using it for? I'm hoping to gather some insights for the sake of internal evangelism.
Any insights are appreciated!
Any thoughts on extending this framework to function as a SCADA process controller? I suppose a measurement could be used to do closed loop control but it seems a new process abstraction layer might be more appropriate, not sure.
Hi,
I have installed Measurement Utility 3.0.3.4 Beta.vipc and created a new project as described.
Now I try to run the "Server Controller main.vi" which says
"Application is broken and cannot be run".
The "Client Controller main vi" is broken. There are many errors regarding "openG Array VIs".
All says that these vis cannot reach privat scope.
Any ideas for solving this problem?
When you installed the VIPC file, did you make sure to install all of the OpenG dependencies it requires? If you launch the VIPC file again, does it indicate that you have all of the correct versions of dependencies installed?
Yes, all dependencies are installed. VIPM says "nothing to do. All the packages are already installed."
I'm using LabVIEW 2013.
That's very odd. Instead of generating the project from the 'Create Project' dialog, try opening the source directly from
[Program Files]\National Instruments\LabVIEW 2013\ProjectTemplates\Source\Framework
If you still see an error, please post a screenshot or email it to me directly at Elijah.Kerry@ni.com
Eli,
I got an error when starting the built controller 'Measurements.exe'. It says (on my german Win7-64): "The file 'Request Compatible Hardware from Client Msg.lvclass' could not loaded"... Tried to rebuild but with same result.
Any Ideas?
I'm attempting to build now from 3.0.3.5 to see if I experience the same issue.