A pure Python implementation of ROS2 functionality with bridging capabilities
Project description
Python ROS2 Engine
A pure Python implementation of ROS2 core functionality with bridging capabilities to interact with native ROS nodes.
Features
- Node creation and lifecycle management
- Publisher and subscriber patterns with Quality of Service (QoS) profiles
- Service and client communication
- Parameter handling with callbacks
- Topic and service discovery
- Timer functionality
- ROS1 bridging capabilities for node/topic/service discovery
- Message translation between Python ROS engine and native ROS
- Configuration with Hydra best practices
Message Types
The Python ROS Engine supports a wide range of message types:
Primitive Types
Bool: Boolean valuesString: String valuesInt8,Int16,Int32,Int64: Signed integer valuesUInt8,UInt16,UInt32,UInt64: Unsigned integer valuesFloat32,Float64: Floating point valuesEmpty: Empty messagesTime: Time valuesDuration: Duration values
Multi-dimensional Array Types
ByteMultiArray: Multi-array of bytesInt8MultiArray,Int16MultiArray,Int32MultiArray,Int64MultiArray: Multi-arrays of integer valuesUInt8MultiArray,UInt16MultiArray,UInt32MultiArray,UInt64MultiArray: Multi-arrays of unsigned integer valuesFloat32MultiArray,Float64MultiArray: Multi-arrays of floating point values
Installation
From PyPI
pip install python-ros-engine
From Source
git clone https://github.com/your-username/python-ros-engine.git
cd python-ros-engine
pip install -e .
Development Installation
For development, you can install with test dependencies:
pip install -e .[test]
For development with documentation building capabilities:
pip install -e .[dev]
Usage
Basic Node
from pyros2 import Node
node = Node('my_node')
# Add publishers, subscribers, services, etc.
node.spin()
Publisher Example
from pyros2 import Node
from pyros2.message import String
class MyNode(Node):
def __init__(self):
super().__init__('publisher_node')
self.publisher = self.create_publisher(String, '/my_topic')
self.timer = self.create_timer(1.0, self.publish_message)
def publish_message(self):
msg = String()
msg.data = 'Hello World!'
self.publisher.publish(msg)
node = MyNode()
node.spin()
Subscriber Example
from pyros2 import Node
from pyros2.message import String
class MyNode(Node):
def __init__(self):
super().__init__('subscriber_node')
self.subscription = self.create_subscription(
String, '/my_topic', self.message_callback)
def message_callback(self, msg):
print(f'Received: {msg.data}')
node = MyNode()
node.spin()
Service Example
from pyros2 import Node
class AddTwoInts:
class Request:
def __init__(self, a=0, b=0):
self.a = a
self.b = b
class Response:
def __init__(self, sum=0):
self.sum = sum
class MyNode(Node):
def __init__(self):
super().__init__('service_node')
self.service = self.create_service(
AddTwoInts, '/add_two_ints', self.add_two_ints_callback)
def add_two_ints_callback(self, request):
response = AddTwoInts.Response()
response.sum = request.a + request.b
return response
node = MyNode()
node.spin()
Client Example
from pyros2 import Node
class AddTwoInts:
class Request:
def __init__(self, a=0, b=0):
self.a = a
self.b = b
class Response:
def __init__(self, sum=0):
self.sum = sum
class MyNode(Node):
def __init__(self):
super().__init__('client_node')
self.client = self.create_client(AddTwoInts, '/add_two_ints')
def send_request(self, a, b):
request = AddTwoInts.Request()
request.a = a
request.b = b
response = self.client.call(request)
return response
node = MyNode()
# Send requests as needed
result = node.send_request(3, 4)
print(f'Result: {result.sum}')
Configuration with Hydra
Create a config.yaml file:
node:
name: my_node
namespace: /
publisher:
topic: my_topic
qos:
reliability: reliable
durability: volatile
depth: 10
subscriber:
topic: my_topic
qos:
reliability: reliable
durability: volatile
depth: 10
Then use it in your code:
from pyros2 import Node
from config.hydra_config import load_config
config = load_config('config.yaml')
node = Node(config.node.name)
Documentation
Comprehensive documentation is available in the docs/ directory and can be built into a static website using MkDocs.
Building the Documentation Site
To build the documentation site locally, first install the development dependencies:
pip install mkdocs mkdocs-material
Or if you have the package installed in development mode:
pip install -e .[dev]
Then build the site:
mkdocs build
The static site will be generated in the site/ directory.
Serving the Documentation Locally
To serve the documentation site locally for development:
mkdocs serve
This will start a local development server at http://127.0.0.1:8000 that automatically reloads when you make changes to the documentation files.
Online Documentation
For the online documentation, visit https://your-username.github.io/python-ros-engine/ (replace your-username with the actual GitHub username).
GitHub Actions Documentation Deployment
The documentation is automatically built and deployed to GitHub Pages using GitHub Actions:
- On pushes to the main branch
- When a new release is published
No manual deployment steps are required.
Bridging with Native ROS
The engine provides bridging capabilities to discover and interact with native ROS nodes:
from pyros2 import Bridge
bridge = Bridge()
try:
native_nodes = bridge.discover_ros_nodes()
print(f"Discovered {len(native_nodes)} ROS nodes")
except Exception as e:
print(f"Bridge connection failed: {e}")
Note: Bridging requires a running ROS master (ROS1) on localhost:11311 by default.
Examples
See the examples directory for complete working examples:
Testing
Run tests with pytest:
python -m pytest tests/ -v
To run tests with coverage:
pip install pytest-cov
python -m pytest tests/ --cov=src/ --cov-report=html
GitHub Actions
The project includes GitHub Actions workflows for:
- Continuous Integration (CI) testing across Python versions 3.8-3.12
- Automatic deployment to PyPI when a release is published
- Automatic documentation deployment to GitHub Pages when a release is published or on main branch updates
To deploy to PyPI, you need to set up a PYPI_API_TOKEN secret in your GitHub repository.
To deploy to Test PyPI, you need to set up a TEST_PYPI_API_TOKEN secret in your GitHub repository.
Contributing
We welcome contributions! Please see our Contributing Guide for details on how to contribute to this project.
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file python_ros_engine-0.1.0.tar.gz.
File metadata
- Download URL: python_ros_engine-0.1.0.tar.gz
- Upload date:
- Size: 29.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60f14d75bf6935cade5fbeed44ae2bdf6856796b0d4ddc10e3630199a71841a5
|
|
| MD5 |
3d14e12db7cc9767113a23a2bfc574f8
|
|
| BLAKE2b-256 |
b60539a85677409173118762013c1d5cc1bb814b0e28c24dac426a195cbccee3
|
File details
Details for the file python_ros_engine-0.1.0-py3-none-any.whl.
File metadata
- Download URL: python_ros_engine-0.1.0-py3-none-any.whl
- Upload date:
- Size: 22.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc72a0c23115542f0f5bea68608277727dae9aee2b1a0b8e09aa913e6f9812e6
|
|
| MD5 |
86ea72ca940a8118d66661018f7ee99b
|
|
| BLAKE2b-256 |
ade8332cc798107d9afe94e2c61f665ff6d95d44f5df255632775909337e4185
|