A pure Python implementation of Gazebo Transport (gz-transport) for easy drone communication, providing pub/sub messaging with automatic discovery.
✅ Pub/Sub Messaging - Publish and subscribe to topics ✅ Automatic Discovery - UDP multicast (ZeroMQ) or liveliness tokens (Zenoh) ✅ Multiple Backends - Choose between ZeroMQ or Zenoh transport ✅ ZeroMQ Transport - Fast message delivery using ZeroMQ (default) ✅ Zenoh Transport - Alternative backend using Zenoh pub/sub ✅ Protobuf Messages - Compatible with Protocol Buffer messages ✅ No C++ Dependencies - Pure Python, no need to compile gz-transport ✅ Network Communication - Works across processes and machines
# Create virtual environment (recommended)
python3 -m venv venv
source venv/bin/activate # On Linux/Mac
# Install the package
cd /path/to/easy-drone-python
pip install -e .This installs easy-drone with integrated gz-msgs (212+ message types included!).
# Install with Zenoh backend support
pip install -e .[zenoh]
# Install with YOLO inference support
pip install -e .[yolo]
# Install with all optional features
pip install -e .[all]
# Install for development
pip install -e .[dev]- Python 3.8+
pyzmq>=25.0.0- ZeroMQ for transport (installed automatically)protobuf>=4.25.0- Protocol buffers (installed automatically, must be 4.25.0 or newer)
- Zenoh Backend:
pip install -e .[zenoh]- For Zenoh transport support - YOLO Inference:
pip install -e .[yolo]- For computer vision examples with YOLO - Development Tools:
pip install -e .[dev]- For testing and development
from gz_transport import Node
from gz.msgs.stringmsg_pb2 import StringMsg
# Create node
node = Node()
# Advertise topic
pub = node.advertise("/chatter", StringMsg)
# Publish message
msg = StringMsg()
msg.data = "Hello World"
pub.publish(msg)from gz_transport import Node
from gz.msgs.stringmsg_pb2 import StringMsg
def callback(msg):
print(f"Received: {msg.data}")
# Create node
node = Node()
# Subscribe to topic
node.subscribe(StringMsg, "/chatter", callback)
# Keep running
import time
while True:
time.sleep(0.1)See the examples/ directory for complete examples. All examples work with the installed easy-drone package.
ZeroMQ Backend (default):
simple_publisher.py- Basic publishersimple_subscriber.py- Basic subscribertopic_list.py- List all available topics
Zenoh Backend:
zenoh_publisher.py- Zenoh-based publisherzenoh_subscriber.py- Zenoh-based subscriberzenoh_cross_backend.py- Demonstrates backend isolation
Computer Vision:
image_yolo.py- YOLO object detection from Gazebo cameragi_bridge.py- GStreamer video bridge from Gazebo
First, install easy-drone:
pip install -e .Then run examples from anywhere:
Terminal 1 (Subscriber):
python examples/simple_subscriber.pyTerminal 2 (Publisher):
python examples/simple_publisher.pyMain interface for communication.
from gz_transport import Node, NodeOptions
# Create node
node = Node()
# With options
options = NodeOptions(namespace="robot1", partition="simulation")
node = Node(options)Methods:
advertise(topic, msg_type, options=None)- Advertise a topic, returns Publishersubscribe(msg_type, topic, callback, options=None)- Subscribe to topicunsubscribe(topic)- Unsubscribe from topicunadvertise(topic)- Stop advertising topictopic_list()- Get list of all known topicsadvertised_topics()- Get topics advertised by this nodesubscribed_topics()- Get topics subscribed by this nodeshutdown()- Clean shutdown
Returned by Node.advertise().
pub = node.advertise("/my_topic", MyMsgType)Methods:
publish(proto_msg)- Publish a protobuf messagepublish_raw(msg_bytes, msg_type)- Publish raw bytesvalid()- Check if publisher is valid
from gz_transport import NodeOptions
options = NodeOptions(
namespace="my_namespace",
partition="my_partition"
)
# Topic remapping
options.add_topic_remap("/old_topic", "/new_topic")from gz_transport import AdvertiseOptions, Scope
options = AdvertiseOptions(
scope=Scope.ALL # PROCESS, HOST, or ALL
)from gz_transport import SubscribeOptions
options = SubscribeOptions(
throttled=True,
msgs_per_sec=10.0
)Problem: Your Python code subscribes but doesn't receive messages, even though gz topic -e works.
Cause: The Python bridge uses a custom discovery protocol that's incompatible with C++ gz-transport. This commonly happens when:
- Gazebo runs in Docker (e.g., publisher at
tcp://172.17.0.1:45943) - Cross-network or cross-subnet communication
- Different discovery protocols between Python and C++ implementations
Solution: Bypass discovery by providing the publisher address directly.
Use the auto-connect script for image streaming:
# Automatically discovers publisher and connects
./examples/gi_bridge_auto.sh /world/default/model/x500/link/camera/sensor/image --fps 30- Get the publisher address:
gz topic -i -t /your/topic
# Output: tcp://172.17.0.1:45943, gz.msgs.Image- Run with
--publisher-address:
GZ_TRANSPORT_IMPLEMENTATION=zeromq python examples/gi_bridge.py \
--gz-topic /your/topic \
--publisher-address tcp://172.17.0.1:45943Or in Python code:
from gz_transport import Node
from gz.msgs.image_pb2 import Image
node = Node(verbose=True)
# Direct connection bypassing discovery
node.subscribe(
Image,
"/camera",
callback,
publisher_address="tcp://172.17.0.1:45943"
)export GZ_PUBLISHER_ADDRESS=tcp://172.17.0.1:45943
python examples/simple_subscriber.py /your/topicGet publisher address for any topic:
./get_publisher_address_auto.sh /your/topic
# Output: tcp://172.17.0.1:45943The discovery system uses UDP multicast (default: 239.255.0.7:11317) to:
- Advertise - Broadcast when a topic is published
- Subscribe - Request discovery of specific topics
- Heartbeat - Send periodic heartbeats (every 1 second)
- Cleanup - Remove stale publishers (after 3 seconds of silence)
Once discovered, actual messages are sent via ZeroMQ:
- Uses
PUB/SUBsockets for topic communication - Publishers bind to random ports
- Subscribers connect to all discovered publishers
- Messages are serialized using Protocol Buffers
┌─────────────────────────────────────────┐
│ Node (Your App) │
├─────────────────────────────────────────┤
│ Publishers │ Subscribers │
│ (ZeroMQ PUB) │ (ZeroMQ SUB) │
└────────┬─────────────┴─────────┬────────┘
│ │
└───────────┬───────────┘
│
┌───────────▼───────────┐
│ Discovery Service │
│ (UDP Multicast) │
└───────────────────────┘
This library supports two transport backends, matching the C++ implementation:
# Use ZeroMQ (default, no env var needed)
export GZ_TRANSPORT_IMPLEMENTATION=zeromq
python3 your_script.py# Use Zenoh backend
export GZ_TRANSPORT_IMPLEMENTATION=zenoh
python3 your_script.pyImportant: All communicating nodes must use the same backend. ZeroMQ and Zenoh nodes cannot communicate with each other.
| Feature | Pure Python | C++ gz-transport |
|---|---|---|
| Pub/Sub | ✅ | ✅ |
| Discovery | ✅ | ✅ |
| ZeroMQ Backend | ✅ | ✅ |
| Zenoh Backend | ✅ | ✅ |
| Services (Req/Rep) | ❌ (TODO) | ✅ |
| Logging | ❌ (TODO) | ✅ |
| Statistics | ❌ (TODO) | ✅ |
| Performance | Good | Excellent |
| Dependencies | Python only | C++, deps |
- Protocol Compatible: Can communicate with C++ gz-transport nodes
- Message Format: Uses same Protobuf serialization
- Discovery: Uses compatible (simplified) discovery protocol
Environment variables:
GZ_TRANSPORT_IMPLEMENTATION- Set transport backend:zeromqorzenoh(default: zeromq)GZ_IP- Set specific IP address for multicast (ZeroMQ only)GZ_RELAY- Set relay addresses (not yet implemented)GZ_PARTITION- Default partition name
- Check firewall allows UDP multicast on port 11317
- Check if multicast is enabled on your network
- Try running with
verbose=True:node = Node(verbose=True)
- Ensure subscriber is connected before publisher starts
- Add a small delay after creating nodes to allow discovery
- Check topic names match exactly
# Make sure easy-drone is installed
pip install -e .
# If you get import errors, reinstall with:
pip uninstall easy-drone
pip install -e .# Terminal 1
python3 examples/simple_subscriber.py
# Terminal 2
python3 examples/simple_publisher.py
# Terminal 3
python3 examples/topic_list.py- Service request/response implementation
- Message throttling
- Topic statistics
- Logging (record/playback)
- Better error handling
- Unit tests
- Performance optimization
Apache 2.0 (same as gz-transport)
Based on the Gazebo Transport protocol specification from: https://github.com/gazebosim/gz-transport
For issues or questions:
- Check existing gz-transport documentation
- File issues on GitHub
- Consult the gz-transport community forums