Skip to main content

A minimal, single-file communication middleware built on Zenoh

Project description

ZRM (Zenoh ROS-like Middleware)

CI

A minimal, single-file communication middleware built on Zenoh, providing a clean and simple API inspired by ROS2 patterns.

https://github.com/user-attachments/assets/3e41d9a7-f553-457b-a879-cae2af45bf63

Features

  • Minimalist: Single-file implementation
  • Type-safe: Protobuf-based serialization with runtime type checking
  • Ergonomic: Pythonic API with sensible defaults

Installation

pip install zrm

Quick Start

import zrm
from zrm.msgs import geometry_pb2

node = zrm.Node("my_node")

# Publish
pub = node.create_publisher("robot/pose", geometry_pb2.Pose2D)
pub.publish(geometry_pb2.Pose2D(x=1.0, y=2.0, theta=0.5))

# Subscribe
sub = node.create_subscriber("robot/pose", geometry_pb2.Pose2D)
if pose := sub.latest():
    print(f"Position: x={pose.x}, y={pose.y}")

node.close()

Protobuf definition:

message Pose2D {
  double x = 1;
  double y = 2;
  double theta = 3;
}

CLI Tools

zrm-topic list                    # List topics
zrm-topic echo robot/pose         # Echo messages
zrm-service list                  # List services
zrm-service call add 'a: 1 b: 2'  # Call service
zrm-action list                   # List actions
zrm-action send fib 'order: 10'   # Send action goal
zrm-node list                     # List nodes

More Examples

See examples/ for complete working examples including services, actions with feedback/cancellation, and graph discovery.


Services

Services use nested Request/Response messages:

import zrm
from zrm.srvs import examples_pb2

def add_callback(req):
    return examples_pb2.AddTwoInts.Response(sum=req.a + req.b)

node = zrm.Node("service_node")
server = node.create_service("add_two_ints", examples_pb2.AddTwoInts, add_callback)
client = node.create_client("add_two_ints", examples_pb2.AddTwoInts)

response = client.call(examples_pb2.AddTwoInts.Request(a=5, b=3))
print(f"Sum: {response.sum}")  # Output: 8

node.close()

Protobuf definition:

message AddTwoInts {
  message Request { int32 a = 1; int32 b = 2; }
  message Response { int32 sum = 1; }
}
Actions

Actions support long-running goals with feedback and cancellation:

import zrm
from zrm.actions import examples_pb2

def execute_fibonacci(goal_handle: zrm.ServerGoalHandle) -> None:
    goal_handle.execute()
    sequence = [0, 1]
    for i in range(1, goal_handle.goal.order):
        if goal_handle.cancel_requested:
            goal_handle.cancel(examples_pb2.Fibonacci.Result(sequence=sequence))
            return
        sequence.append(sequence[i] + sequence[i - 1])
        goal_handle.publish_feedback(examples_pb2.Fibonacci.Feedback(partial_sequence=sequence))
    goal_handle.succeed(examples_pb2.Fibonacci.Result(sequence=sequence))

node = zrm.Node("action_node")
server = node.create_action_server("fibonacci", examples_pb2.Fibonacci, execute_fibonacci)
client = node.create_action_client("fibonacci", examples_pb2.Fibonacci)

goal_handle = client.send_goal(
    examples_pb2.Fibonacci.Goal(order=10),
    feedback_callback=lambda fb: print(f"Progress: {list(fb.partial_sequence)}")
)
result = goal_handle.get_result(timeout=30.0)
print(f"Result: {list(result.sequence)}")

node.close()

Protobuf definition:

message Fibonacci {
  message Goal { int32 order = 1; }
  message Result { repeated int32 sequence = 1; }
  message Feedback { repeated int32 partial_sequence = 1; }
}
Message Organization & Proto Generation

Directory Structure

src/<package>/
├── proto/                 # Proto definitions
│   ├── msgs/              # Message definitions
│   ├── srvs/              # Service definitions
│   └── actions/           # Action definitions
├── msgs/                  # Auto-generated *_pb2.py
├── srvs/                  # Auto-generated *_pb2.py
└── actions/               # Auto-generated *_pb2.py

Generating Python Code

zrm-proto              # Generate from local protos
zrm-proto --dep zrm    # Include dependency protos

Standard Messages

Category Module Types
Messages zrm.msgs.header_pb2 Header
Messages zrm.msgs.geometry_pb2 Point, Vector3, Quaternion, Pose, Pose2D, Twist, PoseStamped
Messages zrm.msgs.sensor_pb2 Imu, Image, CompressedImage, CameraInfo, JointState
Messages zrm.msgs.vision_pb2 Point2D, BoundingBox2D
Services zrm.srvs.std_pb2 Trigger
Services zrm.srvs.examples_pb2 AddTwoInts
Actions zrm.actions.examples_pb2 Fibonacci
Development
git clone https://github.com/JafarAbdi/zrm.git
cd zrm
uv sync

# Linting
uv run pre-commit run -a

# Testing
uv run pytest tests/ -v

Acknowledgements

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

zrm-2.0.0.tar.gz (31.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

zrm-2.0.0-py3-none-any.whl (44.6 kB view details)

Uploaded Python 3

File details

Details for the file zrm-2.0.0.tar.gz.

File metadata

  • Download URL: zrm-2.0.0.tar.gz
  • Upload date:
  • Size: 31.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.14

File hashes

Hashes for zrm-2.0.0.tar.gz
Algorithm Hash digest
SHA256 15c0a7cd385be4f3635074d46475f5f795fa41628ea3c307d0593e55e49bcf6d
MD5 8c944e9d56b5a757d1c024f3c469b385
BLAKE2b-256 de8a4c49b99780203be27971a10ca18806711e030c263a0f9633e6f5ea70c1f1

See more details on using hashes here.

File details

Details for the file zrm-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: zrm-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 44.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.14

File hashes

Hashes for zrm-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 95395a9e4a67bb516061d234e9e14b33b59760c82ac63da884e2806e4cf9588e
MD5 f3068d030abbf779b5904f00ce2215a7
BLAKE2b-256 2bf5bc76109a1e4ca4eaa811e22c3595ce7eed46fedc0ed2d84a06b0c9bcc8c8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page