Files
MARTe-Integrated-Components/README.md
T
Martino FerrariandClaude Opus 4.6 7c5eb31a52 feat: standalone C/C++ UDPS client library
Consuming a UDPStreamer feed so far meant either linking MARTe2 (UDPSClient)
or writing Go (Common/Client/go/udpsprotocol). Common/Client/c fills the gap
for plain C/C++ integrators: two files depending on nothing but libc and BSD
sockets, covering the whole receive path — CONNECT, fragment reassembly,
CONFIG/DATA decoding with dequantisation, keepalives and silence-triggered
reconnect. No threads are spawned; udps_client_poll() does all the work and
runs every callback, so it drops into an existing event loop unsynchronised.

Verified against run_udp_producer.sh at 1 Msps: unicast (120 MiB, no loss) and
multicast with 12-fragment cycles (116k datagrams, no loss).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-08-22 16:51:40 +02:00

262 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MARTe2 Integrated Components
A unified MARTe2 library providing real-time signal streaming and on-the-fly debugging
for control applications built with [MARTe2](https://vcis.f4e.europa.eu/marte2-docs/).
---
## Overview
This repository integrates two complementary capabilities:
| Capability | Component | Purpose |
| --------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------- |
| **Signal streaming** | `UDPStreamer` DataSource | Continuously stream selected signals to a browser-based oscilloscope over UDP |
| **Signal debugging** | `DebugService` Interface | On-demand signal tracing, value forcing, and conditional breakpoints — zero application code changes required |
| **Sine generation** | `SineArrayGAM` | Generate continuous sine-wave arrays for testing and simulation |
| **Time stamping** | `TimeArrayGAM` | Provide time-reference arrays aligned to an RT cycle |
| **Log forwarding** | `TCPLogger` Interface | Forward `REPORT_ERROR` log events to TCP clients in real time |
| **Integrated client** | `Common/Client/go` | Go packages for UDPS protocol and WebSocket hub |
| **Debug web client** | `Client/debugger` | Browser-based debug UI communicating with `DebugService` |
---
## Repository Structure
```
MARTe_Integrated_components/
├── Common/
│ ├── UDP/ UDPS binary protocol header (shared by all components)
│ └── Client/go/ Go packages: udpsprotocol, wshub
├── Source/Components/
│ ├── DataSources/UDPStreamer/ Real-time UDP signal streaming DataSource
│ ├── GAMs/SineArrayGAM/ Sine-wave array generator GAM
│ ├── GAMs/TimeArrayGAM/ Time-reference array GAM
│ ├── Interfaces/DebugService/ Signal tracing/forcing/breakpoint Interface
│ └── Interfaces/TCPLogger/ TCP log-forwarding LoggerConsumerI
├── Test/
│ ├── GTest/ GTest harness for UDPStreamer unit tests
│ ├── Integration/ Integration tests for DebugService
│ ├── Components/DataSources/UDPStreamer/ UDPStreamer unit tests
│ └── Configurations/ MARTe2 config files for tests and demos
├── Client/debugger/ Go web client for DebugService
└── Docs/ Documentation
```
---
## Components
### UDPStreamer DataSource
Streams MARTe2 signals over UDP using the UDPS binary protocol. Clients register by
sending a `CONNECT` packet; the server then sends `CONFIG` (signal metadata) and continuous
`DATA` packets. Features:
- Optional 16-bit quantization (configurable per signal: `QuantizedType`)
- Packed high-frequency bursts (`NumberOfElements > 1` with `SamplingRate`)
- Automatic packet fragmentation for payloads exceeding `MaxPayloadSize`
See `Docs/UDPStreamer.md` and `Docs/Protocol.md`.
### SineArrayGAM
Generates a continuous float32 sine-wave array every RT cycle. Used as a signal
source for testing and demo applications. Configurable: `Frequency`, `Amplitude`,
`Phase`, `SamplingRate`, `NumberOfElements`.
See `Docs/SineArrayGAM.md`.
### TimeArrayGAM
Generates a time-reference uint64 array. Each element holds the timestamp of the
corresponding sample in a packed burst, computed from the RT cycle timestamp and the
configured `SamplingRate`.
`Anchor` selects how the burst is placed in time:
| `Anchor` | `out[k]` |
|---|---|
| `FirstSample` | `input + k · period` |
| `LastSample` | `input (N1k) · period` |
| `Continuous` | `input(first cycle) + (n + k) · period` |
`FirstSample`/`LastSample` re-read the timer each cycle, so a lost RT cycle
(`LinuxTimer` re-phases with `counter += nCycles`) punches a whole-period hole
into the time base even though only one array of samples was produced. Use
`Continuous` when the data signal is itself contiguous (`SineArrayGAM` never
skips phase): it latches the timer once and then advances an internal sample
counter by `N` per cycle, like an acquisition card running off its own clock.
### DebugService Interface
Instruments a running MARTe2 application **without modifying its source code**. On
`Initialise()` it patches the `ClassRegistryDatabase` to wrap all standard
`MemoryMap*Broker` types. When `RealTimeApplication::ConfigureApplication()` runs
afterward the application transparently uses the wrapped brokers.
Capabilities accessible over TCP (port 8080 by default):
- `DISCOVER` — enumerate all signals with type and alias metadata
- `TRACE` — enable/disable high-speed UDP telemetry per signal (with decimation)
- `FORCE` / `UNFORCE` — inject persistent values into signals on the RT path
- `BREAK` — set conditional breakpoints (`>`, `<`, `==`, etc.)
- `PAUSE` / `RESUME` / `STEP` — execution stepping
- `TREE` / `INFO` / `LS` — live ORD navigation
- `VALUE` — read current signal value on demand
- `MSG` — send MARTe2 `Message` to any ORD object
High-speed signal telemetry is streamed as UDP binary datagrams (port 8081).
Logs are forwarded via `TcpLogger` (port 8082).
See `Docs/DebugService.md`.
### TCPLogger Interface
A `LoggerConsumerI` that forwards every MARTe2 `REPORT_ERROR` call to up to 8 TCP
clients on a configurable port. Works as a sidecar to `DebugService`.
### StreamHub Application
Headless C++ hub (`Source/Applications/StreamHub/`) that aggregates multiple
UDPStreamer sources and serves them to oscilloscope clients over WebSocket
(port 8090): ring buffers with wall-clock time calibration, LTTB decimation,
hub-side trigger engine, per-window zoom. Clients: browser SPA
(`Client/webui` + `Client/udpstreamer/static`) and native ImGui desktop client
(`Client/streamhub`). Demo: `./run_streamhub.sh -w -g`; E2E test:
`Test/E2E/suite/run_e2e.sh`.
See `Docs/StreamHub-UserGuide.md`, `Docs/StreamHub-API.md` and
`Docs/StreamHub-Developer.md`.
### UDPS Protocol
The `Common/UDP/UDPSProtocol.h` header defines the shared binary wire format used by
both `UDPStreamer` and `DebugService`. It is intentionally free of MARTe2-specific
dependencies so it can also be used by Go clients (via `Common/Client/go/udpsprotocol`).
See `Docs/Protocol.md`.
---
## Build
### Prerequisites
- MARTe2 built and installed (set `MARTe2_DIR`)
- MARTe2-components built and installed (set `MARTe2_Components_DIR`)
- GCC toolchain, make
- Go 1.21+ (for clients)
### Setup
```bash
# Edit env.sh to set MARTe2_DIR and MARTe2_Components_DIR, then:
source env.sh
```
### Build all C++ components
```bash
make -f Makefile.gcc core
```
### Build and run tests
```bash
make -f Makefile.gcc test
source env.sh
./Build/x86-linux/Test/Integration/IntegrationTests
```
### Build Go clients
```bash
# Integrated UDPS web client
cd Common/Client/go && go build ./...
# Debug web client
cd Client/debugger && go build ./...
```
### Clean
```bash
make -f Makefile.gcc clean
```
---
## Quick Start
### 1. Stream signals with UDPStreamer
Add to your MARTe2 config:
```text
+Streamer = {
Class = UDPStreamer
Port = 44500
MaxPayloadSize = 1400
Signals = {
Voltage = { Type = float32; Unit = "V" }
}
}
```
Launch the web client:
```bash
cd Common/Client/go
./udpstreamer-webui --streamer 127.0.0.1:44500 --listen :8080
```
Open `http://localhost:8080` and drag signals onto plots.
### 2. Debug a running application with DebugService
Add to your MARTe2 config (as a sibling of `+App`):
```text
+DebugService = {
Class = DebugService
ControlPort = 8080
UdpPort = 8081
LogPort = 8082
}
+Logger = { Class = TcpLogger; Port = 8082 }
```
Launch the debug client:
```bash
cd Client/debugger
./debugger --listen :9090
```
Open `http://localhost:9090`, explore the object tree, trace signals, force values.
---
## Documentation
| Document | Contents |
| ----------------------------- | -------------------------------------------------------------- |
| `Docs/Protocol.md` | UDPS binary wire protocol specification |
| `Docs/UDPStreamer.md` | UDPStreamer DataSource configuration reference |
| `Docs/UDPS-C-Client.md` | Standalone C/C++ UDPS receiver library (`Common/Client/c`) |
| `Docs/SineArrayGAM.md` | SineArrayGAM configuration reference |
| `Docs/DebugService.md` | DebugService TCP API and architecture |
| `Docs/Tutorial.md` | Step-by-step tutorial covering both components |
| `Docs/WebUI.md` | Web client user guide |
| `Docs/StreamHub-UserGuide.md` | StreamHub oscilloscope user guide (web + ImGui clients) |
| `Docs/StreamHub-API.md` | StreamHub WebSocket protocol (commands, events, binary frames) |
| `Docs/StreamHub-Developer.md` | StreamHub internals, threading, time base, build & E2E tests |
| `ARCHITECTURE.md` | System architecture overview |
---
## License
Licensed under the EUPL v1.1 (see individual source files for copyright notices).