fixed multicast updated tests

This commit is contained in:
Martino Ferrari
2026-07-25 16:46:25 +02:00
parent 3e0a481c13
commit 915a192b16
16 changed files with 542 additions and 75 deletions
+123 -9
View File
@@ -8,7 +8,9 @@ thread.
## Key Features
- **Zero-copy RT path** — `Synchronise()` only locks, copies signal memory, and posts a semaphore.
- **Single-client model** — one client at a time; a new CONNECT replaces the previous session.
- **Unicast and multicast** — unicast (default): single client at a time, new CONNECT replaces
the previous session. Multicast: multiple clients receive data simultaneously by joining
a multicast group; control traffic uses a TCP listener.
- **Packet fragmentation** — large payloads are split into ≤ `MaxPayloadSize`-byte datagrams,
each with a header carrying fragment index and total count so the client can reassemble them.
- **Signal quantization** — `float32`/`float64` signals can be linearly quantized to
@@ -16,6 +18,8 @@ thread.
- **Temporal arrays** — signals with `NumberOfElements > 1` can carry per-sample time
metadata via `TimeMode` and `TimeSignal`, enabling high-frequency burst transmission
(e.g. 1 000 samples per RT cycle at 1 MSps).
- **Publishing modes** — `Strict` (one packet per RT cycle), `Accumulate` (batch N snapshots
then flush on size or time limit), `Decimate` (send every Nth cycle).
---
@@ -26,10 +30,22 @@ thread.
Class = UDPStreamer
// Network
Port = 44500 // UDP port the server listens on (default: 44500)
Port = 44500 // UDP port (unicast) or TCP control port (multicast)
MaxPayloadSize = 1400 // Maximum bytes per UDP datagram (default: 1400)
// Must be > 17 (header size). Tune for MTU.
// Multicast (optional — omit for unicast mode)
MulticastGroup = "239.0.0.1" // IPv4 multicast address (224.0.0.0/4)
Interface = "eth0" // Multicast-bound interface (mandatory when MulticastGroup is set)
DataPort = 44501 // UDP port for multicast DATA (default: Port+1)
// Publishing mode (optional)
PublishingMode = "Strict" // Strict | Accumulate | Decimate
// For Accumulate mode:
MinRefreshRate = 120.0 // Flush frequency in Hz (required for Accumulate)
// For Decimate mode:
Ratio = 10 // Send 1 packet every N RT cycles (required for Decimate)
// Background thread (optional)
CPUMask = 0x2 // CPU affinity mask for the network thread
StackSize = 1048576 // Stack size in bytes (default: 1 MiB)
@@ -66,12 +82,18 @@ thread.
### Top-level Parameters
| Parameter | Type | Default | Description |
| ---------------- | ------ | --------- | ------------------------------------------- |
| `Port` | uint16 | 44500 | UDP server port |
| `MaxPayloadSize` | uint32 | 1400 | Max payload bytes per UDP datagram (min 18) |
| `CPUMask` | uint32 | 0 (any) | Background thread CPU affinity |
| `StackSize` | uint32 | 1 048 576 | Background thread stack size in bytes |
| Parameter | Type | Default | Description |
| ---------------- | ------ | ---------------- | --------------------------------------------------------------------------- |
| `Port` | uint16 | 44500 | UDP server port (unicast) or TCP control port (multicast). Values ≤ 1024 produce a warning. |
| `MaxPayloadSize` | uint32 | 1400 | Max payload bytes per UDP datagram (min 18) |
| `MulticastGroup` | string | *(absent)* | IPv4 multicast address (e.g. `"239.0.0.1"`). Must be in 224.0.0.0/4. Absent or empty = unicast mode. |
| `Interface` | string | *(absent)* | Network interface for multicast binding (e.g. `"eth0"`). **Mandatory** when `MulticastGroup` is set. |
| `DataPort` | uint16 | Port+1 | UDP port for multicast DATA datagrams. Ignored in unicast mode. |
| `PublishingMode` | string | Strict | `Strict`: send every RT cycle. `Accumulate`: batch until size/time limit. `Decimate`: send every Nth cycle. |
| `MinRefreshRate` | float64| — | Flush frequency in Hz. **Required** when `PublishingMode` = `Accumulate`. |
| `Ratio` | uint32 | — | Send 1 packet every `Ratio` RT cycles. **Required** when `PublishingMode` = `Decimate`. |
| `CPUMask` | uint32 | 0xFFFFFFFF (any) | Background thread CPU affinity bitmask |
| `StackSize` | uint32 | MARTe2 default | Background thread stack size in bytes |
### Per-signal Parameters
@@ -113,6 +135,62 @@ wire_value = (uint16)(normalized × 65535)
---
## Network Modes
### Unicast (default)
The server opens a single UDP socket on `Port`. The client initiates the session by sending a
CONNECT packet to that port. The server replies with a CONFIG packet on the same socket and
subsequently sends DATA packets directly to the client's address. One client at a time; a new
CONNECT evicts the previous client.
### Multicast
Enabled by setting `MulticastGroup` to a valid IPv4 multicast address (224.0.0.0/4).
The `Interface` parameter is **mandatory** and specifies the network interface to bind.
The server opens a TCP listener on `Port` for control traffic and a UDP socket aimed at
`MulticastGroup:DataPort` for data traffic. The client:
1. Connects to `Port` via TCP and sends a CONNECT packet.
2. Receives the CONFIG packet over TCP.
3. Joins the multicast group (`MulticastGroup:DataPort`) to receive DATA packets.
Multiple clients may receive data simultaneously by joining the same group.
---
## Publishing Modes
### Strict (default)
Sends one DATA packet for every `Synchronise()` call (every RT cycle). Simplest and lowest
latency.
### Accumulate
Batches multiple RT-cycle snapshots into a single DATA packet. All signals (scalars and arrays)
are accumulated: one full snapshot per RT cycle. The batch is flushed when either:
- **Size condition**: adding one more sample would exceed `MaxPayloadSize`.
- **Time condition**: `1/MinRefreshRate` seconds have elapsed since the last flush.
The maximum batch count is computed automatically from `MaxPayloadSize` and the total wire size
of all signals. Scalar signals with `Unit="us"` or `"ns"` are auto-promoted as the per-sample
FullArray time reference for all other scalars.
Requires `MinRefreshRate` (Hz) to be set.
### Decimate
Sends one DATA packet every `Ratio` RT cycles, dropping intermediate cycles. Only the most
recent snapshot at the Nth cycle is sent.
Requires `Ratio` (≥ 1) to be set. `Ratio = 1` is equivalent to `Strict` mode (a warning is
logged).
---
## Broker
UDPStreamer uses `MemoryMapSynchronisedOutputBroker` for output signals. This broker is
@@ -151,7 +229,7 @@ PrepareNextState() ← opens UDP server socket, starts background threa
---
## Example: minimal scalar streaming
## Example: minimal scalar streaming (unicast)
```
+Data = {
@@ -168,6 +246,26 @@ PrepareNextState() ← opens UDP server socket, starts background threa
}
```
## Example: multicast with accumulation
```
+Streamer = {
Class = UDPStreamer
Port = 44500 // TCP control port
MulticastGroup = "239.0.0.1" // Enables multicast mode
Interface = "eth0" // Mandatory for multicast
DataPort = 44501 // UDP data port (default: Port+1)
MaxPayloadSize = 1400
PublishingMode = "Accumulate"
MinRefreshRate = 60.0 // Flush at least 60 times/s
Signals = {
Time = { Type = uint32; Unit = "us" }
Voltage = { Type = float32; Unit = "V"; RangeMin = -10.0; RangeMax = 10.0; QuantizedType = uint16 }
}
}
```
## Example: high-frequency burst
```
@@ -198,3 +296,19 @@ With `MaxPayloadSize = 1400`, a single 1000-element float32 signal produces:
payload = 8 B (HRT timestamp) + 4 B (T0/uint32) + 4000 B (float32×1000) = 4012 B
fragments = ceil(4012 / 1383) = 3
```
## Example: decimated output
```
+Streamer = {
Class = UDPStreamer
Port = 44500
PublishingMode = "Decimate"
Ratio = 10 // Send 1 packet every 10 RT cycles
Signals = {
Time = { Type = uint32; Unit = "us" }
Position = { Type = float64; Unit = "mm" }
}
}
```