Zenoh Publisher
Node ID: zenohPublisher · Role: Sink · Realtime config: no
Description
Publishes pipeline data through Zenoh; the companion zenoh-bridge-ros2dds process exposes the keys as native ROS 2 DDS topics. Avoids the RustDDS/Fast-DDS interop quirks of the direct ROS2 Publisher.
Inputs / Outputs
- Inputs:
FusedPose,FusedVehiclePoseV2,GlobalFusedPose - Outputs: (none)
Config aliases
ZenohSink, zenohSink, zenohPublisher
Properties
The following fields are exposed in the node’s Properties panel in the UI. Types map to UI widgets (e.g. string → text input, number → numeric, boolean → toggle, select → dropdown, json → JSON editor).
| Key | Label | Type | Default | Description / Notes |
|---|---|---|---|---|
key | Zenoh Key (PoseStamped) | string | fusionhub/pose | Zenoh key expression for the PoseStamped publication. The bridge maps fusionhub/pose to ROS 2 topic /fusionhub/pose. Use only forward slashes; no leading slash. Set empty to disable. |
bridgeEndpoint | Bridge Endpoint | string | tcp/[::1]:7447 | Zenoh locator of the zenoh-bridge-ros2dds process. Default is IPv6 loopback (matches the bundled bridge’s default listen socket). Override to tcp/<ip>:7447 if the bridge runs on another host, or set empty to use peer mode + multicast scouting (only do this if you know why; scouting over machines with many NICs causes connect-fail noise). |
autoSpawnBridge | Auto-spawn Bridge Process | boolean | true | When on (default), fusionhub spawns the bundled zenoh-bridge-ros2dds process automatically when this sink starts. Turn off if you’re running the bridge yourself. |
bridgeRosDomainId | Bridge ROS_DOMAIN_ID | number | 0 | ROS_DOMAIN_ID env var passed to the spawned bridge. Must match the value used by your ROS 2 nodes. |
bridgeCyclonedssUri | Bridge CycloneDDS URI (advanced) | string | "" | Optional. Path or file:// URI to a hand-written CycloneDDS XML config. Overrides the structured fields below. Empty = use the structured fields (or auto-detect if those are also empty). |
bridgeStaticPeers | Bridge Static Peers (comma-separated IPs) | string | 127.0.0.1 | Comma-separated IPs of remote DDS participants the bridge should unicast SPDP to (bypasses multicast discovery). Defaults to 127.0.0.1 for the common case where fusionhub and ROS 2 run on the same machine. Override with the LAN IP of the ROS 2 box when running cross-machine, e.g. 192.168.140.78. |
bridgeNetworkInterface | Bridge Network Interface (IP) | string | 127.0.0.1 | IP of the network interface CycloneDDS should bind to. Defaults to 127.0.0.1 (loopback) for same-machine ROS 2 setups. Override with the LAN IP (e.g. 192.168.140.99) for cross-machine. Use this to skip Hyper-V / VPN / virtual adapters. |
frameId | Frame ID | string | map | — |
maxRateHz | Max Publish Rate (Hz) | number | 200 | Cap the outgoing rate to this many messages per second. 0 = unlimited. |
stampWithWallClock | Stamp With Wall Clock | boolean | true | Set header.stamp to current system time at publish-time instead of the data’s own timestamp. On by default for replay; turn off for live feeds where original capture time matters downstream. |
invertYaw | Invert Yaw | boolean | true | Negate FusedVehiclePoseV2 yaw before publishing. Use when downstream expects the opposite rotation convention. |
publishTf | Publish TF | boolean | true | Also broadcast each pose as a tf2_msgs/TFMessage on the standard ROS 2 /tf topic. Useful for rviz2 and most ROS 2 consumers. |
tfKey | Zenoh Key (TF) | string | tf | Zenoh key expression for the /tf publication. Default tf ↔ ROS 2 topic /tf. Rarely changed. |
gnssKey | Zenoh Key (NavSatFix) | string | fusionhub/gnss | Zenoh key expression for sensor_msgs/NavSatFix publications, used when GlobalFusedPose data arrives at the sink. Set empty to disable. |
tfParentFrame | TF Parent Frame | string | map | — |
tfChildFrame | TF Child Frame | string | oxts_link | — |
tfPositionOffset | TF Position Offset | vector3 | {"x":0.0,"y":0.0,"z":0.0} | — |
tfRotationOffset | TF Rotation Offset | quaternion | {"w":0.5,"x":0.0,"y":0.0,"z":0.5} | Right-multiplied into the transform rotation: output = base * offset. Output is renormalised, so non-unit values are fine. Default (w=0.5, z=0.5) applies a 90° yaw to align our body frame with the typical ROS REP-103 convention. |
Example node definition
A full node definition in config.json looks like the block below. Paste it under the sinks key of your config, keyed by the node’s instance name (any identifier; it doesn’t have to match the node ID).
{
"sinks": {
"zenohPublisher": {
"inputEndpoints": [
"inproc://fusedPose_data",
"inproc://fusedVehiclePoseV2_data",
"inproc://globalFusedPose_data"
],
"inputDataFilter": [
"FusedPose",
"FusedVehiclePoseV2",
"GlobalFusedPose"
],
"settings": {
"autoSpawnBridge": true,
"bridgeCyclonedssUri": "",
"bridgeEndpoint": "tcp/[::1]:7447",
"bridgeNetworkInterface": "127.0.0.1",
"bridgeRosDomainId": 0,
"bridgeStaticPeers": "127.0.0.1",
"frameId": "map",
"gnssKey": "fusionhub/gnss",
"invertYaw": true,
"key": "fusionhub/pose",
"maxRateHz": 200,
"publishTf": true,
"stampWithWallClock": true,
"tfChildFrame": "oxts_link",
"tfKey": "tf",
"tfParentFrame": "map",
"tfPositionOffset": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"tfRotationOffset": {
"w": 0.5,
"x": 0.0,
"y": 0.0,
"z": 0.5
}
}
}
}
}
Field reference
| Field | Purpose |
|---|---|
inputEndpoints | List of upstream endpoints this node connects to (outEndpoint / dataEndpoint values from upstream nodes). |
inputDataFilter | Optional whitelist of data types. Messages whose type isn’t in the list are dropped at the subscriber. |
settings | All user-configurable fields — see the Properties table above. |
Connections can also be declared at the top-level
connectionsarray whensettings.explicitConnectionsistrue, as an alternative to fillinginputEndpointson each node.