01-15-2015 10:32 AM
Hi all,
I tried searching for this, it seems common enough, but I'm not sure I used the right set of words:
I'm receiving data from a device in packets. Each packet contains multiple frames, each frame contains two sub-frames, and each sub-frame contains several data channels. In my vi, the packet is a cluster, the frames are clusters, and the sub-frames are clusters, all typedef'ed.
What I want to do, is take the initial big cluster, and split the data into a cluster of arrays, one per data channel, without generating spaghetti.
The "decimate array" function would work beautifully to do the job, but alas, it only operates on arrays, not clusters, and it seems my clusters cannot be converted to arrays.
Is there something I'm missing? I've attached a high-level picture...note I'm not an artist. 🙂 The values "n" and "m" are fixed, so there is no variability
Solved! Go to Solution.
01-15-2015 10:49 AM
Can you share your type definitions of the clusters? Then we could suggest ways to manipulate your actual data, or changes to your cluster structure that would make it easier to rearrange. It would also let us understand why you can't convert your cluster to an array. Are all the types of data the same?
01-15-2015 12:29 PM - edited 01-15-2015 12:35 PM
Hi nathand,
I'm not sure I can send the exact clusters, but here is a "close enough" approximation.
It seems that the cluster structure *can* be converted to arrays, but after that, I'm stumped. I'm relatively new to Labview, and I may have spent too much time staring at a C++ IDE, so I might not fully understand the memory management aspects of LabView, to properly do this split.
01-15-2015 12:56 PM
Sorry, but I'm stuck on an older version of LabVIEW at the moment... could you save it back to LabVIEW 2012 or earlier, and I'll take a look?
01-15-2015 12:56 PM
I think I have it now. I converted the "devices" to arrays, then appended the arrays to each other. So, from the base "packet", I unbundled the cluster into 8 data streams (4 frames, two devices per frame). With 4 "frames" and 2 "devices", it took 7 appends to get the job done, though, which when I apply this to the real setup, is going to turn into spaghetti, and fast.
Maybe I should get rid of the "device" concept, and just make the frame typedef include all the channels directly. Then I only need to merge the frames into a single array.
01-15-2015 01:07 PM
By "append" do you mean "Build Array"? Can you use "Cluster to Array" instead?
Also note that if you have a cluster where all the final elements are identical, regardless of how many nested clusters there are, then you can Type Cast to an array of that final element type. For example, if all the actual data in your cluster is single-precision floats, you can Type Cast to an array of SGL.
If you can upload a screenshot, or your code saved back to an earlier version, I'll try to provide more specific assistance.
01-15-2015 01:12 PM
Nope, I meant "Append Array". "Build Array" kept building 2D arrays, which didn't work, where append array worked fine.
All of the data is U32's, so I will look into typecasting.
Attached is a build for Labview v12 (which should be 2012, right?)
01-15-2015 01:26 PM
Right-click on Build Array and choose "Concatenate Inputs" so you'll get a 1-D array.
If you get rid of the "Header" and "Footer" elements, you can wire your overall cluster to Cluster to Array, which will give you an array of Frame clusters, which you can then put through a For loop with Cluster to Array, which will give you a 2-D array, that you can reshape/decimate/extract columns or rows as necessary. Or, in newer versions of LabVIEW, you can right-click on the loop output tunnel and choose the option to concatenate, giving you a 1-D array. However, I suspect that the 2-D array will actually work well for you - you'll have frames on one axis, and data channels on the other.
If you need the Header and Footer to remain part of the overall cluster, add one more level of nested cluster (there's no memory/speed penalty) containing all the frames, so that you can unbundle just the data.
Is there any possibility of reading the data into an array in the first place, instead of a cluster? That might be easier.
01-15-2015 01:39 PM
I don't think I can read it into an array; I'm receiving from a UDP packet, so LabView's variable-length arrays make that hard.
Good idea to typedef the frames into a single cluster, that cleaned everything up very nicely.
I've accepted your prior suggestion as a solution, and attached is a screenshot showing the final, cleaned up, code. Much, MUCH simpler than I thought it would be.
01-15-2015 01:48 PM
@dziems wrote:
I don't think I can read it into an array; I'm receiving from a UDP packet, so LabView's variable-length arrays make that hard.
Not sure I understand the issue here. You can unflatten directly from a string into an array. In this case, you need to tell Unflatten that the string does not contain the number of elements. When you set that input false, it unflattens as many elements as it can before it runs out of bytes. If your header and footer are a different data type than the rest of the data, then you'll need to extract them from the string prior to unflattening, but other than that it's simple.