Although quiet on the master branch, a lot is going on on -dev. Here's a
summary of what's coming (and will become the long awaited v1.0).
new blocks
lsdb-intf and ubx-dbus
A D-Bus interface block that exposes the full node API
(create/remove blocks, connect ports, set/get configs, load USC
models, ...) over D-Bus. The companion ubx-dbus CLI provides
interactive access from the shell.
The plugin extension lets you register custom D-Bus objects at
runtime by loading Lua plugin files, so application-specific
interfaces can sit alongside the standard org.ubx.node API.
The block is based on the
lsdbus bindings. Essentially,
this permits creating coordination interfaces that can cleanly and
safely interact with the hard real-time processing without impacting
real-time performance.
lfrb
A new lock-free ring buffer iblock based on a minimal internal
liblfq implementation which is based on a Vyukov MPMC queue. This
replaces the external liblfds dependency which didn't support
arm64. Strongly typed, hard-real-time safe.
gpio
Linux GPIO block using libgpiod v2. Ports are created dynamically from the
gpios config array — each input line becomes an out-port, each output line
becomes an in-port (type unsigned int). Supports active-low polarity, pull
bias, and emit-on-change mode.
iio
Linux Industrial I/O blocks via libiio for ADCs, DACs, IMUs, and
environmental sensors. Two variants:
ubx/iio— polled, synchronous sysfs read each step; also supports DAC outputubx/iio_buf— buffered, hardware samples atsampling_frequency; ptrig drains the kernel buffer
Ports are created dynamically from the channels config; type is always
double (physical scaled value).
gps
GPS block that reads from gpsd via its shared
memory interface. Emits a single gps out-port of type ubx_gps_data with
position, velocity, fix quality, and uncertainty fields.
webgraph
A luablock that serves an interactive browser graph of the running node
using React Flow + ELK.js. Blocks are shown as nodes (colour-coded by state)
with ports, configs, and iblock edges. The page auto-refreshes and re-runs
the ELK layered layout. Requires luasocket and json.lua; JS libs are
fetched from CDN on first load. Self-trigger it at a low rate alongside your
composition — no separate process needed.
ubx-launch gained a matching -webgraph [PORT] flag to attach one
automatically:
$ ubx-launch -c threshold.usc -webgraph
This replaces the old webif block, which was removed — it had grown too
complex and unmaintainable.
math_double / math_float
Applies any single-argument math.h function element-wise to an input array,
with optional per-element mul and add (y = f(x) * mul + add). The
function is selected via the func config string ("sin", "sqrt", "log",
etc.).
udpsink
A luablock-based block that streams input ports as a single JSON datagram per
step over UDP — primarily for live-plotting with
PlotJuggler. Port names and types are declared via
lua_str; ports are created dynamically at init:
{ name="sink", type="luablock:udpsink" },
-- ...
{ name="sink", config = {
lua_str = [[
ports = { x="double", v="double" }
host = "127.0.0.1"
port = 9870
]],
} },
For RT decoupling, run the sink on its own thread at a lower rate
(thread=1, period=100) with deep connection buffers (buffer_len=N);
each step drains the full buffer so no samples are lost on the RT side.
$ ubx-launch -c udpsink.usc
other changes
blockdiagram: direct luablock loading
.usc compositions can now instantiate Lua blocks directly using the
luablock:NAME type prefix — no need to manually import the luablock module,
create an instance, and configure lua_file separately:
blocks = {
{ name="ctrl", type="luablock:mycontroller" },
},
The name is resolved against the standard microblx block prefixes.
luablock: self-triggering
luablock now supports built-in self-triggering via the thread and period
configs. For non-RT management or interfacing tasks this eliminates the need for
a dedicated ptrig:
config = { thread=1, period=100 } -- self-trigger at 100 ms
ptrig: SCHED_DEADLINE support
ptrig now supports Linux EDF scheduling via sched_policy = "SCHED_DEADLINE". Timing parameters are passed via the sched_deadline
config (runtime_ns, deadline_ns, period_ns); deadline_ns and
period_ns default to the period config when 0. After each chain trigger
sched_yield signals budget exhaustion to the kernel. Budget overruns are
caught via SIGXCPU and counted on the deadline_throt_cnt out-port. The
sched_deadline in-port allows runtime parameter updates without
reconfiguration.
ptrig: dynamic period port
ptrig gained a period in-port for runtime adjustment of the trigger period
without reconfiguration.
const: runtime in port
ubx/cconst and ubx/iconst gained an in port. Writing to it
updates the held value at runtime — without a reconfigure
cycle. Example use-case: update dynamic configuration safely via the
lsdb-intf block.
ubx-log: syslog forwarding and daemon mode
ubx-log gained two new options: -s tees log messages to syslog (selectable
facility via -f LOCAL0..7), and -d daemonizes via libdaemon with a PID
file under /run to prevent duplicate instances.
improved enum, struct and union support
Anonymous structs and unions are now handled correctly by cdata.tolua. Named
structs and unions gained a custom converter registration mechanism, and enums
are properly reflected, with new test coverage throughout.
Lua API docs
ubx.lua is now fully documented with
ldoc. The generated API
reference is published here and
built as part of the standard CMake doc target.
build: switched to CMake
The build system was migrated from make to CMake, reducing boilerplate and improving IDE and cross-compilation support.
test cleanup
Tests were reorganised into suites with a single runner, CI was updated to
Debian trixie, and the lsdb-intf tests are now part of the standard CI run.
various bug fixes
Several minor fixes across ubx.lua, blockdiagram, node cleanup, module
reloading, and timing utilities.

