Live-plotting microblx data with udpsink

May 30, 2026

Instrumenting a running RT system for live visualisation is tricky: you want to observe signals without disturbing timing. Sockets, memory allocation, and formatting code have no business on an RT thread.

udpsink solves this by running as a separate, self-triggered luablock that drains buffered connections and streams the samples as JSON datagrams over UDP — one per sample, ready for PlotJuggler's UDP server input. The RT chain never touches a socket.

Setup

Instantiate it as luablock:udpsink and declare ports and destination via lua_str:

blocks = {
    { name="sink", type="luablock:udpsink" },
},
configurations = {
    { name="sink", config = {
        thread = 1,
        period = 100,  -- self-trigger at 10 Hz, independent of the RT ptrig
        lua_str = [[
            ports = { ts="double", sin="double", cos="double" }
            host  = "127.0.0.1"
            port  = 9870
        ]],
    } },
},

Each ports entry becomes an input port — key is the port name and JSON field name, value is any registered ubx_type. Structs and arrays are serialised too, not just scalars.

Connections

Wire your signals to the sink ports as usual, with deep buffers to absorb the rate gap between the fast RT producer and the slow NRT sink:

connections = {
    { src="ramp.out", tgt="sink.ts",  config = { buffer_len = 16 } },
    { src="sin.y",    tgt="sink.sin", config = { buffer_len = 16 } },
    { src="cos.y",    tgt="sink.cos", config = { buffer_len = 16 } },
},

Each sink step drains the full buffer and sends one datagram per sample, so no data is lost and the RT chain never blocks.

The ts port

When the sink runs at a lower rate than the producer, wall-clock timestamps collapse the time axis — ten samples produced at 100 Hz all appear stamped at the same 10 Hz read instant. To fix this, name one port ts and udpsink uses it as the JSON timestamp instead:

{ src="ramp.out", tgt="sink.ts", config = { buffer_len = 16 } },

Any monotonically increasing signal works: a ramp, a step counter, a cycle index. In PlotJuggler, select ts as the timestamp field and the time axis unfolds correctly.

Running

$ ubx-launch -t 10 -c udpsink.usc

udpsink streaming sin/cos/tan to PlotJuggler over UDP

In PlotJuggler: Streaming → UDP Server → port 9870, select ts as the timestamp. A full working example is in the repo.