We need two models to communicate via UDP connection. One method we are currently prototyping is having the UDP communication setup directly in a model, rather than through a custom device.
We were able to build the model in Simulink, and it deploys fine (target: cRIO), but when I go to run the model, the model status (from the model control UI object) says "invalid mappings". Note that I am deploying a simple model that only writes a square wave out on UDP address and port. There are no other models, no custom devices, and no channel mappings in the system definition file.
What are we doing wrong?
I found some other literature regarding the use of UDP within the model itself rather than a custom device, but it never got answered: https://forums.ni.com/t5/NI-VeriStand/UDP-in-Veristand-Model-instead-of-Custom-Device/m-p/3646098
Is there a specific reason you’re wanting to do UDP within the model compared to other methods you mentioned like implementing in a custom device?
The custom device route is usually best for this situation, unless there are other things about your project we haven't considered that would make it a bad fit. There are some considerations that may help show that a custom device might be a better fit.
There are some good examples of UDP custom devices on the web. The UDP Data Link Custom Device is a good example of how you could implement UDP communication in VeriStand. The code is provided as-is, but would be a better place to get started than from scratch.
Chris D. | Applications Engineer | National Instruments
"Is there a specific reason you’re wanting to do UDP within the model compared to other methods you mentioned like implementing in a custom device?"
Yes. To put it bluntly, Custom Devices are more difficult for our team to edit, build, implement, and manage than just doing the changes directly in a model for various reasons.
For the UDP message, we need to take several arrays of data in, and then interleave all of the elements together to get the correct messaging order. Using the instrument add-on, we can create arrays of channels, but I have not been able to figure out an easy way to get the output string to look like [Array1.Element1][Array2.Element1][Array1.Element2][Array2.Element2]...etc.
Additionally, by bringing the data from the model out so that you can connect it to a UDP custom device, our modeling team (or HIL team) has to convert all of the vector data to scalars since we've found no way to send vector data out to the physical world via a Custom Device (model-to-model communication is the only kind that works with vector data).
This is starting to become a real performance issue as well since some of the array sizes are 3000+ elements (we're maxing out the UDP data length in some cases). When you consider multiple UDP messages of that size, the channel count from all of the scalar data starts to get very big, very quick. Like on the order of ~500k channels. We've already had it crash on us several times.
Not sure why my original reply didn't save, but I will try to reproduce it.
The main reason we are considering directly from model is that it is far easier for our modeling team to implement these changes directly in the model than trying to edit a Custom Device.
We currently have large variable length arrays of data that are produced by some of our models that need to be sent out on UDP. The elements of those arrays need to be interleaved. For example, say we have Array 1 (100 elements) and Array 2 (100 elements). We need the UDP string to look like
So far, we've found no easy way to do this other than edit the custom device, which is going to take some time and effort, and the model outputs could change. Conversely, our modeling team could implement these changes very quickly.
Additionally, we need a solution that scales pretty well. Some of the array sizes are 3000+ elements. If we were able to do UDP comm directly, we would not have to manage all of those individual elements. But, since Veristand does not allow the use of vector data to communicate with Custom Devices, or at least not that we've been able to find so far (model-to-model vector data is fine), we have to scalar-ize all of those elements. When you are working with multiple UDP messages with dozens of variable length arrays and upwards of thousands of elements each (some of the messages max out the UDP data length), the channel count gets very big, very fast. We're talking on the order of ~500k channels, which completely kills the performance of the system (we've had it crash several times).
We ended up taking the Instrument Add-On Custom Device and modifying it by adding a custom UDP protocol to the drop down list. We basically copy/pasted the UDP protocol (although it wasn't just a simple copy/paste procedure). In this custom UDP protocol, we have some VIs that are intercepting the string on the reader and writer to do some custom formatting of the output and input data, respectively, to meet the protocol requirements. It wasn't an easy or straightforward task, but we think we're close to having something that might work after a few more edits to the VIs that are intercepting the code.
Note: the actual string modification VIs are fairly simple to place, but figuring out how to add a new protocol to the Instrument Add-on Device and get them built correctly to work on a cRIO running linux64 took one of our senior labview/NI developers quite a bit of time to figure out.