08-11-2022 05:21 AM
Hello Community,
i am currently working on a project where i want to use the from NI given SVE (Shared Variable Engine) to transfer some of my data inside and outside of my RT-Programm/RT-System. Therefore i try to implement some shared variables where some of them has also RT FIFO enabled. These RT-FIFO enables network published shared variables are used inside of a timed structure which is running on 10ms for testing purposes (future goal is to reduce this time). I tried to implement a RT-FIFO enabled variable to publish the status of the programmed code inside the timed structure but got stuck on a problem. The typedefinition (1) i am using has also an array which holds a second typedefenition (2) of four double variables (all datatypes of (1) and (2) are RT-FIFO valid -> no strings, variants, etc.). During the implementation and testing of this shared variable i got some problems that the array variable was not working correctly. My next step was to isolate the array with the typedefintion (2) and create another shared variable with the same settings as before:
1. Variable Type: Newtork Published
2. Data Type: 1D array of TypeDef (Cluster of 4 Dbl-elements)
3. Use Buffering: enabled
4. Buffer size (bytes): 500000
5. Single Writer: enabled
6. RT-FIFO: enabled
7. FIFO Type: Single Element
With this configured shared variable i am only able to insert an array with a size of 2 into this variable. It seems that the maximum limit is capped by something inside of LabVIEW. When i compare this variable with a shared variable with a native array of double than i am able to change the number of elements which can be stored on the register "RT_FIFO". The needed byte size is calculated automatically and i am able to use the implemented max. number of elements for the array (to not get a byte cap i set the buffer byte size to 500000 bytes on my typedef-shared-variable). The default value for this parameter inside LabVIEW is 2. My assumption is that in the background LabVIEW is using this default parameter to cap the max. number of array entries for an array of typedefinitions and does not make this parameter changeable in the configuration window of the shared variable properties. Does anybody know something about this or has running into a similiar problem.
I know that there are workaround for this issue, but i want to know if i am making an error during my configuration or if this is an issue inside of LabVIEW.
My workaround-concepts:
1. Using of the RT-FIFO VIs: With these VIs the system is working and i am able to change the max. number of elements in an array but i am losing the comfort-option of the network-published over the SVE.
2. Using a separate shared variable for every dbl-value inside my typedefinition and transfer these via the SVE. Con is that this concept is not flexible for modifications and makes the programm more complex.
LabVIEW Version 2020 SP1 (Real-Time Module 20.0.0)
Heinz
08-11-2022 08:38 AM
First, I'm not very familiar with RT FIFOs, so I apologize if this is incorrect.
RT FIFOs must have fixed byte width, like you mentioned. But that means they also cannot store arrays. So I think when you use arrays with an RT FIFO, LabVIEW flattens them into the FIFO, then unflattens them when you read.
For example, if your RT FIFO type is (Array of (Cluster of 4 dbls)), I think the underlying RT FIFO type is actually just (Cluster of 4 dbls). If you then write one 3-element Array, it will use 3 RT FIFO slots, even though you only wrote once.
If using RT FIFO VIs directly, you can see there are inputs for size (the FIFO depth) and for elements in array (hard-coded array size). I expect LabVIEW will allocate the internal RT FIFO size as size x elements in array. When you use Shared Variables, you can't set elements in array, so I guess that's your problem. Especially, when you enable Single Element, it is probably limiting the size of array you can put in. But I'm surprised you got 2 elements instead of 1.
By the way, I think the buffer is separate from the RT FIFO. It would look like this:
[Program 1] RT FIFO (size: 1) --> [Network Stack] Buffer (size: 500k) --> [Program 2] RT FIFO (size: 1)
See this very useful article from NI describing how it works. Your configuration is Figure 14.
It might be better practice to separate the RT FIFO and Network Communication into different variables. You would use a Single Process Shared Variable (or RT FIFO VIs) to move data from your timed loop to a network loop. Then use a Network Published Shared Variable (without RT FIFO) to publish the data across the network. It should keep flexibility for the future and you don't need a variable for every dbl.
08-11-2022 10:11 AM - edited 08-11-2022 10:15 AM
Hello OneOfTheDans,
as I understand it the underlying mechanism for the RT FIFO VIs and the shared variables with RT FIFO are the same. Every of the both implementation has its pro and cons regarding programmatic casting, simplicity of use and further options. So when I want to use a RT-FIFO-System based variable than these two should behave in the same manner. But for arrays out of typedefinitions they don't (RT-FIFO-VIs are working and the shared variables not).
The configuration option that you mentioned for the RT-FIFO-VIs "If using RT FIFO VIs directly, you can see there are inputs for size (the FIFO depth) and for elements in array (hard-coded array size). I expect LabVIEW will allocate the internal RT FIFO size as size x elements in array. When you use Shared Variables, you can't set elements in array, so I guess that's your problem. Especially, when you enable Single Element, it is probably limiting the size of array you can put in. But I'm surprised you got 2 elements instead of 1." is also available for the configuration of a shared variable with RT-FIFO enabled (see first picture below). But when I am using a typedefintion which is an array of typedefed DBLs inside than the option for "Number of arrays" and "Number of elements" is missing completely (see second picture below). Maybe only the visualization of these variables is missing in the configuration of the shared variable and the RT-FIFO-System in the background is capping the number of elements to its default value of 2. Like you said it is very odd that it is capped at the value of 2.
The storing of an array inside an RT-FIFO itself shouldn't be problem. Like shown in the picture and like you said in your comment the parameters to determine the space that need to be reserved can be calculated under the condition that no datatype is used which itself has no fixed byte size. In this case you get a broken error on the connection line of the typedefinition to the "Create FIFO"-VI and in the configuration window for the shared variables the RT-FIFO segments gets disabled and greyed out.
As far as i know the reservation of the space for such a RT-FIFO with preallocation of the data space should work after the following approach. The system is allocating N chunks (Queue size of the RT-FIFO) where every chunk has a byte size of B. B is calculated after the used datatypes and the given parameters for "number of elements in array", "datapoints in waveform", etc.. For example a DBL array with with a number of elements of 4 the system needs to allocate 4x64byte (in reality more because the datatype of an array itself also needs bytes for storing its information). These 4x64byte are always allocated also when only two entries in the element are being used. Every of these N chuncks has a pointer address which is stored in a list with a length of N. For accessing the list and with this accessing the data inside the RT-FIFO you have two pointer where one is for reading and the other one is for writing. When you write with the write-pointer you are accessing the chunk where the pointer points to at the specific list entry. After that the write-pointer increments and looks at the next chunk address pointer. Same goes for the reading. When the RT-FIFOs are implemented in such a way than I see no problem with storing an array with datatypes or typedefinitions which has fixed byte sizes. I know that this explanation is very simplified and the there is much more to consider to get such a system running. When I am missing something here or if I am wrong with my assumption than please correct me.
I will do some test to try out your suggestion with separating the RT-FIFO communication with the network communication.
Heinz
08-11-2022 04:45 PM
Yes, I agree RT Shared Variables and RT FIFO VIs should behave the same way, and I agree it looks like some problem with the Shared Variable dialog box when you are using a typedef. I can't offer much help, but maybe you can open a support request with NI?
08-12-2022 12:33 AM
Hello OneOfTheDans,
sometimes it is good to discuss an issue with other LV-Programmers to check if you are running in the wrong direction or if you are using some programming mechanisms wrong. This is also help and can get you some good ideas for improvement.
I will wait a few days to give others the possibility to take part on this topic and when there is no direct solution I will create a support request.
Heinz
09-15-2022 12:56 AM
UPDATE:
After working on the issue with the NI support a bug report was created with the number of 2147257. Now we have to wait for the fix in future LabVIEW releases.