Skip to main content

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.

PyPI version License Python Versions

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 values
  • String: String values
  • Int8, Int16, Int32, Int64: Signed integer values
  • UInt8, UInt16, UInt32, UInt64: Unsigned integer values
  • Float32, Float64: Floating point values
  • Empty: Empty messages
  • Time: Time values
  • Duration: Duration values

Multi-dimensional Array Types

  • ByteMultiArray: Multi-array of bytes
  • Int8MultiArray, Int16MultiArray, Int32MultiArray, Int64MultiArray: Multi-arrays of integer values
  • UInt8MultiArray, UInt16MultiArray, UInt32MultiArray, UInt64MultiArray: Multi-arrays of unsigned integer values
  • Float32MultiArray, 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

python_ros_engine-0.1.0.tar.gz (29.1 kB view details)

Uploaded Source

Built Distribution

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

python_ros_engine-0.1.0-py3-none-any.whl (22.3 kB view details)

Uploaded Python 3

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

Hashes for python_ros_engine-0.1.0.tar.gz
Algorithm Hash digest
SHA256 60f14d75bf6935cade5fbeed44ae2bdf6856796b0d4ddc10e3630199a71841a5
MD5 3d14e12db7cc9767113a23a2bfc574f8
BLAKE2b-256 b60539a85677409173118762013c1d5cc1bb814b0e28c24dac426a195cbccee3

See more details on using hashes here.

File details

Details for the file python_ros_engine-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for python_ros_engine-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dc72a0c23115542f0f5bea68608277727dae9aee2b1a0b8e09aa913e6f9812e6
MD5 86ea72ca940a8118d66661018f7ee99b
BLAKE2b-256 ade8332cc798107d9afe94e2c61f665ff6d95d44f5df255632775909337e4185

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