LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Flexible cluster?

I'm not 100% certain that I understand the problem.  Let me describe a situation that I faced, and my solution -- if it is relevant to your problem, I can provide more details.

 

We are running behavioral tests to study how well people can track sounds (in the dark).  We perform a series of trials where we move speakers around, play sounds, flash lights, ask the subject to point with a Laser Pointer (mounted on a gimbal so we know where it is being pointed), etc.  We design the Experiment using an Excel Worksheet where each Row is a Trial and each Column is one of 70-100 parameters that can be independently varied (how many sound pulses, how much time between pulses, how long is the pulse, what is its frequency range, etc.).

 

We need to "capture" the data from the Excel row to give us the "parameters" for the Trial.  Partly because some parameters are integers, some Floats, some strings, we designed a "Trial Cluster" that basically mimics the Excel row, each element being named from the name of the corresponding Excel Column.  Our Experiment Header File is an XML file that has an entry for every Trial consisting of this Cluster, saved as XML.

 

And then one of the Students wants to do something "a little different -- I want to use Headphones instead of movable speakers, so I'll need an additional 10 parameters added to the WorkSheet to hold Headphone-specific parameters".  Great!  That means a redesign of the Cluster (grrr).  

 

When we originally designed this system, we wanted to keep things as simple as possible, and avoid humongous Worksheets if certain Trial Cluster parameters were not being used in the Study.  So we said "If you are not using a Parameter, simply delete that Column from the WorkSheet".  When we start the program, we read the WorkBook, parse the first row of the Trials WorkSheet, and map the Excel Columns to the Trial Cluster using the Column "names" contained in the first Row.  We also flag which Cluster Elements are not present, and assign them a suitable Default Value (typically <blank> for Strings and 0 for numerics, though we use the unsigned equivalent of -1 for Delays, or "Delay forever" (=Don't Do That).  So we can easily accomodate missing Columns, but how do we accomodate new columns?

 

Simple (sort of).  We redesign a new "Master Excel WorkBook" with all of the Columns present, then run a LabVIEW Scripting routine that parses the WorkBook and creates for us a brand new Trial Cluster (we also increment the Version Number of the software -- at present, we are on our fourth Excel-driven Version).  Because our Cluster is defined by a LabVIEW TypeDef, adding elements to the Cluster has a minimal impact on the existing Code (though we do check to make sure "Trial Delay" doesn't get substituted for "Pulse Width" within the code) -- we just have to add new code to handle the new Cluster elements.

 

There are a few more "complications", particularly at the Analysis end, but as the Software has progressed through its four Versions, experiments designed for the first Version's WorkBook continue to run just fine (remember, if a parameter isn't specified in the WorkBook, it is given a default value that the software interprets as "Do not do this").  Since we've "only" gone through four Versions, I've only had to run the Create Trial Cluster From Excel routine four times (note -- I ran it quite a few more times -- debugging, demonstrations, etc.), and "propagate" the new TypeDef throughout the code a few times.  Made updates "relatively painless" (I'd say a week or three to implement and test).

 

And we didn't need to make any changes to the XML for saving data.  Of course, when reading back the data, we did need to know which Version of the code wrote the data so we could use an appropriate Trial Cluster to convert the XML back to something that "made sense".  That's when I started using LabVIEW Libraries (I'm a relative new-comer to them ...).

 

Bob Schor

0 Kudos
Message 11 of 27
(1,781 Views)

Have you heard of LabVIEW Containers?

0 Kudos
Message 12 of 27
(1,774 Views)
Like I said in my first post, you can always parse the data manually. This goes for either XML or JSON. In fact it would be easier with JSON as that format is a lot cleaner.

Mike...

Certified Professional Instructor
Certified LabVIEW Architect
LabVIEW Champion

"... after all, He's not a tame lion..."

For help with grief and grieving.
0 Kudos
Message 13 of 27
(1,769 Views)

@NauOrNever wrote:

Looking at how to convert it back to a cluster, i need the datatype again.

Is it different with this json library? Again, i need to get the data structure of a file without knowing the structure.


One CAN work with an entirely unkown data structure with the LAVA JSON library, but I thought you just needed to handle minor changes, like added elements in your cluster.  These are trivial, since the library uses your supplied default value for any missing elements.  This differs from libraries that are stricter about types, like the inbuilt LabVIEW cluster-to-JSON/XML tools.

 

BTW: LAVA JSON library can also (if you dive into it) handle partially-known data-structures, such as "I know my data is an array of clusters with each cluster containing a "Module Name" string and a "Config" JSON object (of varying format dependant on module type)".   Pass the "Config" JSON to the named module and let it interpret it.

0 Kudos
Message 14 of 27
(1,752 Views)

Oli,

     The short answer is "Barely", the longer answer is that I click on your link and get this:

Unexpected Error.png

Bob Schor

0 Kudos
Message 15 of 27
(1,739 Views)

Ooops,

 

standard answer of a programmer: used to work yesterdaySmiley Very Happy

 

This is the direct link

 

I have just tested it, honestly! Smiley Happy

0 Kudos
Message 16 of 27
(1,708 Views)

Generally i want to open any xml file and create a cluster. 

What i can do is open the file and read the xml-string. I´ve just done that and had a look at its size: Putting each line as element into an array gives me 53290 elements!

That is for the cluster im using filled with values. Doing the same with the default cluster gives me about 600 lines. I did manage to fill the default cluster with values by comparing each line of the xml strings and then add new lines into the default xml string.

So, the default cluster is a good basis as the elements in it will probably always be needed. But if i have some more requirements, lets say my new xml string contains more elements ( not more values for a single array but a completely new array added to it) it doesnt work anymore. I thought about anylyze this xml string and create the datatype by myself, but that seems to be pretty painful.

Of course this new xml string that creates a new cluster should update my default cluster. 

 

I hope you understand this better now, otherwise I´ll try again 🙂

 

However, i´m not bound to xml documents, but  i need to be able to convert the existing documents into the new documents.

 

@Bob: I´m not exactly sure if this is my problem. But using master-slave was the original idea. I was thinking about using excel sheets, but as i have a cluster containing clusters it´s not possible to write it into excel?

 

@Mike: If i understand it correctly, this is possible with xml parser? I just dont understand how this works by reading the labview help.. I tried it but i already get an error with loading the document.

 

@Oli: I didnt try it yet, but it looks great for adapting in run time. How does this behave for opening new files? 

 

@drjdpowell: Adding new elements while runtime might be an option that i need too. The big problem is elements added to my file before i open it in labview.

0 Kudos
Message 17 of 27
(1,691 Views)

I haven't tried yet.

 

Only saw Chris' presentation at the European CLA Summit. I'm also using variant tables a lot, this is a bit more sophisticated stuff

0 Kudos
Message 18 of 27
(1,687 Views)

I just found this post : http://forums.ni.com/t5/LabVIEW/Dynamically-Creating-Clusters/m-p/3137825/highlight/true#M902488.

Regarding the second question this is pretty much what I´m looking for.

 

Bob_Schor, I think you mentioned the same project you described in your answer in this post?

"Could you do something like parse the XML and save the components as an Array of Variants?  To display it, you could read the Variant, deduce its type, and display it as appropriate.  Alternatively, you could skip the Variant part and as you read it, save it in a suitable-for-display string representation.  Crude, but it might get the job done."

 

Regarding the first lines of the post: Is that actually working?

0 Kudos
Message 19 of 27
(1,662 Views)

@NauOrNever wrote:
Bob_Schor, I think you mentioned the same project you described in your answer in this post?

"Could you do something like parse the XML and save the components as an Array of Variants?  To display it, you could read [snip]

 

Regarding the first lines of the post: Is that actually working?


Yes, since any data can be converted to a variant, yet contains the information about the original datatype, you can use an array of variants to handle any and all data.

Look at the OpenG Cluster to ini-file for some good example and code referrence. (i put a bunch of work into doing a similar thing before hearing about that, but use my own one just for the sake of it)

/Y

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 20 of 27
(1,646 Views)