Susi Server

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

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).

KeyLabelTypeDefaultDescription / Notes
keyZenoh Key (PoseStamped)stringfusionhub/poseZenoh 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.
bridgeEndpointBridge Endpointstringtcp/[::1]:7447Zenoh 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).
autoSpawnBridgeAuto-spawn Bridge ProcessbooleantrueWhen on (default), fusionhub spawns the bundled zenoh-bridge-ros2dds process automatically when this sink starts. Turn off if you’re running the bridge yourself.
bridgeRosDomainIdBridge ROS_DOMAIN_IDnumber0ROS_DOMAIN_ID env var passed to the spawned bridge. Must match the value used by your ROS 2 nodes.
bridgeCyclonedssUriBridge 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).
bridgeStaticPeersBridge Static Peers (comma-separated IPs)string127.0.0.1Comma-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.
bridgeNetworkInterfaceBridge Network Interface (IP)string127.0.0.1IP 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.
frameIdFrame IDstringmap
maxRateHzMax Publish Rate (Hz)number200Cap the outgoing rate to this many messages per second. 0 = unlimited.
stampWithWallClockStamp With Wall ClockbooleantrueSet 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.
invertYawInvert YawbooleantrueNegate FusedVehiclePoseV2 yaw before publishing. Use when downstream expects the opposite rotation convention.
publishTfPublish TFbooleantrueAlso broadcast each pose as a tf2_msgs/TFMessage on the standard ROS 2 /tf topic. Useful for rviz2 and most ROS 2 consumers.
tfKeyZenoh Key (TF)stringtfZenoh key expression for the /tf publication. Default tf ↔ ROS 2 topic /tf. Rarely changed.
gnssKeyZenoh Key (NavSatFix)stringfusionhub/gnssZenoh key expression for sensor_msgs/NavSatFix publications, used when GlobalFusedPose data arrives at the sink. Set empty to disable.
tfParentFrameTF Parent Framestringmap
tfChildFrameTF Child Framestringoxts_link
tfPositionOffsetTF Position Offsetvector3{"x":0.0,"y":0.0,"z":0.0}
tfRotationOffsetTF Rotation Offsetquaternion{"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

FieldPurpose
inputEndpointsList of upstream endpoints this node connects to (outEndpoint / dataEndpoint values from upstream nodes).
inputDataFilterOptional whitelist of data types. Messages whose type isn’t in the list are dropped at the subscriber.
settingsAll user-configurable fields — see the Properties table above.

Connections can also be declared at the top-level connections array when settings.explicitConnections is true, as an alternative to filling inputEndpoints on each node.

Loading documentation…