12-16-2014 08:54 AM
Hello all,
I'm getting very very frustrated as I cannot find a way to pass
an asynchronous VI with a Teststand cluster that mirror a LV
cluster using a queue.
It works if you wire the Teststand cluster to the VI is there is
a suitable command to link to. Yet the VI doesn't have any
connector, it waits for a queued cluster, read it from the
PropertyObject through 'GetValVariant, 'perform some magic
and is supposed to return another cluster to Teststand using
a notification
I can read single elements of the enqueued cluster, but can't
cast it into a LV cluster using, say, the good old 'VariantToData'
that indeed works beautifully withing LV.
Same happens when I try to return a cluster to Teststand
using 'SetValVariant' even though both the Teststand cluster
and the LabView cluster are of the same format and structure.
The Teststand 'Wait' notifier action is linked to the right cluster
property, but Labview fails at 'SetValVariant' because not of
the right type, even if I casted the data to variant.
I'm wondering if I'm doing wrong or Teststand and Labview
are just not engineered to transparently work together.
Here's the example I'm trying to set up, but reading the
cluster fails, while the 'False' alternative works (123.00)
Setting the notifier cluster fails too, but setting the
elements indivualy fails also because Labview doesn't
know what are 'Conformité' and 'Commentaires' in
the 'True' alternative, even though I tested the whole
hierarchical tree.
You might have figured it out, but I really really need to
get this working, and I cannot understand where the
failure is (beside between chair and keyboard) because
the principle works in LabView.
David Koch
Solved! Go to Solution.
12-17-2014 02:29 AM - edited 12-17-2014 02:36 AM
OK, this morning, reading this I thought I could get lucky :
So I tried this :
Yet I got this :
So obviously Labview detects the cluster coming from
Teststand, yet doesn't provide a purposeful method such
as 'GetValContainer' or 'GetValCluster' to extract the data
so that you just have to cast with 'VariantToData'.
Is that correct ?
What's the better way to fit the incoming Teststand cluster
into its mirror Labview cluster ? After all the 'custom data
format' created in Testand was created upon its Labview
counterpart, so it should be easy to make both clusters
match.
David Koch
12-17-2014 10:58 AM - last edited on 10-20-2024 11:53 AM by Content Cleaner
I've found something really helpful :
https://forums.ni.com/t5/LabVIEW/extracting-array-of-labels-in-a-cluster/td-p/506847#M241996
I have a main cluster that contain child clusters, one
for each instrument. I can unbundle the main cluster,
select a child cluster and pass it to this VI as a variant
and I will get it parsed into atomic pieces.
Now the idea is to do the same with a 'PropertyObject'
coming from TestStand, match each element and either
copy the data down from TS to LV, or up from LV to TS.
The methodology might be quite the same :
1- Parse the hierarchy of the cluster/container
2- Look for the name, clean it to match TS naming
3- Check the datat type
4- Copy the value
Hence the additional work would be as follow :
5- Create/allocate/copy arrays
6- Ensure covering every data type (widget)
Man, I'm not going to be without job. Jobless perhaps,
but not without some duty to carry out 🙂 It's rather fun
to stumble upon so simple data copying problem in
soon-to-be 2015, while clusters were meant to simplify
people's task by bundling a large quantity of data all
together. And you still cannot do it easily between TS
and LV. I've seen 2004 or 2005 topics dealing about
the very same issue, obviously not yet solved. Boring.
David Koch
12-31-2014 07:28 AM - edited 12-31-2014 07:51 AM
Hello all,
Happy Easter !
Sorry, too fast, New Year first 😕
Well, I'm currently stuck with my concept as I have no
idea how I should deal with variants without using the
OpenG library. I prefer to stick to bare metal and use
the almost not documented VariantType.lvlib (found
in "vi.lib\Utility\VariantDataType\") to mess with the
variant construction.
Let me tell you a story...
Once upon a time... yeah, nothing quite fancy right
now, common approach to the problem, boring I
confess.
You'll find attached below the current VIs composing
the main Teststand <-> Labview interface that is
planned to perform raw bulk container<->cluster
conversion on the fly, without... I repeat, WITHOUT
specific coding beside initializing the component
to learn the fingerprint of the container/cluster.
The main idea comes from nathand's original VI
(Get Cluster Element Names LV8.vi) found in the
link provided above. The cluster is decomposed
into atomic elements, name and data type queued
in separate arrays. Hence it is possible to 'identify'
a container/cluster by the array of its elements
(length and data representing the parent level).
I created a teststand counterpart of the algorithm
that decompose the PropertyObject enqueued
from the Teststand queue. I compared the two
arrays and they were similar, hence confirming
that is was the right way to go.
Here's what should be done on each side of the
communication :
'TCS_teststand_2.0.0.vi'
LV:Initialisation : 1- Learn the fingerprint of the clusters
LV:Initialisation : 2- Jump to wait enqueued data
LV:Attente : 1- Loop to wait enqueued data
LV:Attente : 2- Identify data structure (fingerprint)
LV:Attente : 3- Execute associated action
'TCS_main_2.0.3.seq'
TS:Initialisation : 1- Create an inter process shared queue (and notifier)
TS:Initialisation : 2- Start LV interface in separate thread
TS:Initialisation : 3- Enqueue the notifier cluster to send their structures
This last step allows the LV interface to 'learn' the
Teststand's alternative names due to a different
naming convention. The fingerprints will now
store not only the Labview cluster's structure
and names, but also the Teststand's data type
and specific names.
This is mostly used by the interface to construct
a PropertyObject container that would be sent
back to Teststand using a notifier (SetEx), see
LV:Notification (current algorithm unfinished)
using the Teststand names, not the Labview's,
ensuring the match on notifier reception.
There is some variant converter helpers that
are used to format the variant/PropertyObject
into a fingerprint, and one that convert the
variant's names and data type from Teststand
to Labview, and vice versa.
I'm a bit stuck with these helpers because I have
some trouble finding how to construct the variant
and bundle variants into a cluster, inside another
variant, that could be finally casted to a cluster
using 'VariantToData'.
I think I'm very close to finish the interface that
would solve many people's trouble dealing with
data passing between Teststand and Labview,
so if someone would be kind enough to provide
the missing tiny bit of help, that would be great.
Sorry I'm pretty bad at drawing, so you'll get
only textual explanations of the concept, but
I hope it was clear enough.
And again, Happy New Year 🙂
David Koch
12-31-2014 07:33 AM - last edited on 10-20-2024 11:54 AM by Content Cleaner
The remaining VIs, the other missing VIs can
be found in the OP or in similar thread dealing
with this issue :
BTW I'm a bit stuck there since my Teststand
evaluation has elapsed, as I had to spend
more time than expected on solving inter
process communication between Teststand
and Labview.
Geee...
Don't hesitate to ask me for clarifications 🙂
David Koch
12-31-2014 08:08 AM - last edited on 10-20-2024 11:57 AM by Content Cleaner
Here's some links that I used as informations
and inspirations to develop the interface, maybe
that might be some help too :
https://knowledge.ni.com/KnowledgeArticleDetails?id=kA03q000000YGK0CAO&l=en-US
https://forums.ni.com/t5/NI-TestStand/using-unstructured-TS-data-and-labview-variants/td-p/651181
https://forums.ni.com/t5/NI-TestStand/LabVIEW-Utility-for-Initializing-a-TestStand-Variable-Containe... (recursive though)
https://www.ni.com/docs/en-US/bundle/labview/page/handling-variant-data.html
https://www.ni.com/docs/en-US/bundle/teststand/page/labview-data-types-in-teststand.html
https://www.ni.com/docs/en-US/bundle/labview/page/vi-memory-usage.html
David Koch
12-31-2014 08:59 AM
And of course, the Teststand sequence...
David Koch
01-07-2015 10:34 AM - edited 01-07-2015 10:38 AM
OK, I get it, 'Cluster Info' returns an array of variant that
you can type check more or less recursively. But it
removes all variant data within, leaving an empty shell.
Good job buddies.
Time to retire myself.
David Koch
01-15-2015 04:33 AM - last edited on 10-20-2024 11:58 AM by Content Cleaner
OK guys, I abandon any hope I had about getting this working.
This is a WIP Teststand container/Labview cluster relay engine.
Teststand 2013 -> TCS_main_2.0.4.seq (runs TCS_teststand_2.0.0.vi)
Labview 2013 -> TCS_teststand_2.0.0.vi (runs TCS_instruments_2.0.0.vi)
Labview 2013 -> TCS_instruments_2.0.0.vi (instruments interface)
The main idea was to catch Teststand enqueued containers,
convert them into a variant, analyse their structure and
match them with their Labview cluster counterpart.
The engine gets initialized with 'learning' the Labview
clusters data structures, storing the names and data type
of the different elements, as well as the cluster hierarchy.
A target data type format and an associated action are also
stored for each container/cluster identified.
Then the engine waits for incoming Teststand enqueued
containers, convert them into a variant, analyse their
structure and *TRY* to match them with the stored
previously analysed Labview clusters counterparts.
These are what I call the 'fingerprints' 🙂
The main three problems were... are :
1- Different naming convention (TCS_string_teststand_name_convert_2.0.0.vi)
2- Different data type format (TCS_variant_tree_convert_2.0.0.vi)
3- Different data structure (TCS_propertyobject_tree_parse_2.0.0.vi)
I think I was very close to solve these issues, but I'm
running out of time. As a contractor, I've already spent
more than a man-month worth of work on this. Which is
far too much considering my dead-line.
I'm pretty sad to leave this unfinished, it would have
been awesome to get the cluster relaying engine up and
running, having just to enqueue a Teststand container
to get something done automatically on the other end
and just wait for a notification sent back for analysis.
What remains to be done are the following, as an exercise
left for the reader :
A- 'Explode' the data structure to match Teststand's
simpliest yet more verbose data format
That means for instance that a Labview waveform have to
be converted into a 3 datas cluster. You can read the
following document but it's not very clear about how
Labview data type formats are converted into their
corresponding Teststand counterpart :
https://www.ni.com/docs/en-US/bundle/teststand/page/labview-data-types-in-teststand.html
Beware, that implies a lot of trial and error, like
creating a large Labview cluster with all the data
type supported, import it into Teststand and create
a custom data type, then compare each converted
data type one by one.
B- Point A would improve the matching between Teststand
containers and Labview clusters.
With a more mirroring data structure, it will indeed
help 'TCS_fingerprint_search_2.0.0.vi' to compare
the Teststand container structure with the corresponding
Labview cluster structure, the elements' naming
convention still being different.
C- Data format conversion is to be done, place holders
are ready to be filled.
There's still a lot of work to do in 'TCS_variant_tree_convert_2.0.0.vi'.
Keep in mind that the 'FileGlobals.tcscluster' data type
mirrors (Teststand wise) the 'TCS_instruments_2.0.0.ctl'
type definition.
That means that a string was not converted into a waveform.
Data format should be very close from each other. Hence
there is no needs to focus too much on such "exotic" data
format conversions.
Thanks again to all the people that invested some time
into trying to help me solving this issue.
Thanks to nathand for his non-recursive cluster parser.
David Koch