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.py
Terminal 2 (Publisher):
python examples/simple_publisher.py
Main 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:45943
Or 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/topic
Get publisher address for any topic:
./get_publisher_address_auto.sh /your/topic
# Output: tcp://172.17.0.1:45943
The 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/SUB
sockets 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.py
Important: 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:zeromq
orzenoh
(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