udp/udp.packets.json
5 minute read
The UDP module exchanges one fixed-size datagramA datagram is one UDP message: a block of bytes sent in one go, without a connection. It arrives whole or not at all.
in each direction with another computer or a PLC, in real time, next to the regular client connection. udp.packets.json sets the layout of the two datagrams, and udp.link.json connects their fields to the rest of the application.
└── udp
├── udp.link.json
└── udp.packets.json
Turn it on
The module is set up in the UdpComm block of config.json. This is the block of the standard robot configuration, where it is off:
"UdpComm": {
"Amount": 1,
"Enable": false,
"Configurations": [
{
"Name": "Device101",
"Enable": true,
"ListenOnPort": 16385,
"ReplyToSource": false,
"SendCycleTime": 0.1,
"SendToHost": "192.168.2.101",
"SendToPort": 16385,
"Packets": "udp/udp.packets.json",
"Linking": "udp/udp.link.json"
}
]
}
Each item in Configurations is one connection, with its parameters under root/UdpComm/<Name>/.
| Field | What it does | Default |
|---|---|---|
Enable (block) |
false turns the whole module off |
true |
Amount |
How many items of Configurations are used; your license can limit this further |
1 |
Name |
The connection’s name in the parameter tree | Undefined00, Undefined01, … |
Enable (item) |
false skips this connection |
true |
ListenOnPort |
The UDP port the controller receives on | 16385 |
ReplyToSource |
true: answer every valid datagram that arrives, to the address it came from. false: send on the controller’s own clock |
true |
SendCycleTime |
With ReplyToSource false: send a datagram every this many seconds. 0 sends nothing |
0 |
SendToHost |
With ReplyToSource false: the address to send to |
127.0.0.1 |
SendToPort |
With ReplyToSource false: the port to send to |
16385 |
Packets |
The packets file. Required | |
Linking |
The link file | none |
Restart Motorcortex after changing the block.
How the data flows
The packets file creates a parameter for every field, under Outgoing and Incoming. The link file fills the outgoing fields; incoming fields land in the tree by themselves. This example is a shortened version of the one that ships with the UDP module:
The packets file
Outgoing is what the controller sends, Incoming what it expects to receive. Each field has a name and a Type:
{
"Outgoing": {
"frameCounter": { "Id": 1, "Type": "uint32" },
"positionTargetArray": { "Id": 2, "Type": "float[6]" }
},
"Incoming": {
"frameCounter": { "Id": 1, "Type": "uint32" },
"command": { "Id": 2, "Type": "uint32" }
}
}
Typeis a data type with an optional length in brackets, as in user parameters:bool,int8toint64,uint8touint64,floatordouble, andfloat[6]for six of them.- Order decides the layout. The fields go into the datagram in the order of the file, back to back without padding, little-endian.
bool,int8anduint8take 1 byte,int16anduint162,int32,uint32andfloat4,int64,uint64anddouble8. Idis not read. Keep it as a note for yourself, but the order is what counts.- Size must match. A received datagram is only accepted when its length is exactly the size of
Incoming; anything else is dropped without a message.
The other side must use the same layout: your Outgoing is its Incoming. Between two Motorcortex applications, copy the Outgoing section of one into the Incoming section of the other. The standard robot configuration sends and expects a single frameCounter:
{
"Outgoing": {
"frameCounter": { "Id": 1, "Type": "uint32" }
},
"Incoming": {
"frameCounter": { "Id": 1, "Type": "uint32" }
}
}
The link file
udp.link.json is a link file like the ones in linking/, applied when the module starts. Link into the Outgoing fields to put data on the wire: a field without a link stays 0. Incoming values appear under Incoming without a link; link from them only when the application should act on them.
The module counts every datagram it sends in root/UdpComm/<Name>/frameCounter, but does not put the count on the wire by itself. The standard udp.link.json links it into the outgoing field:
{
"Version": "1.0.0",
"Groups": [
{
"Name": "frameCounter",
"SystemMode": "All",
"Enable": true,
"Links": [
{
"Source": { "Path": "root/UdpComm/Device101/frameCounter" },
"Destination": { "Path": "root/UdpComm/Device101/Outgoing/frameCounter" }
}
]
}
]
}
The other side can echo the counter back, so the application can compare Incoming/frameCounter with its own count and see that the whole loop is alive.
Warning
A link from an Incoming field to a control input lets the other computer move the machine. When the connection drops, the incoming values go to 0 by default, so make sure 0 is a safe value for every input you link, or set keepIncomingValuesWhenDisconnected.
Connection monitoring
Each connection watches whether valid datagrams keep arriving. These parameters are under root/UdpComm/<Name>/:
| Parameter | What it shows or sets | Default |
|---|---|---|
connected |
true while valid datagrams arrive |
|
Errors/receiveWarningTimeout |
Seconds without a valid datagram before Errors/receiveWarning |
0.1 |
Errors/receiveErrorTimeout |
Seconds without a valid datagram before Errors/receiveError, and connected goes false |
0.2 |
keepIncomingValuesWhenDisconnected |
true keeps the last incoming values when the connection drops, instead of setting them to 0 |
false |
autoResetErrors |
true clears the errors as soon as a valid datagram arrives again |
false |
resetErrors |
Write true to clear the errors |
|
receivePacketDelay |
The time between the last two valid datagrams, in s | |
frameCounter |
The number of datagrams sent |
With the defaults, the other side has to send at least every 0.1 s to keep the connection free of warnings.