Python bindings for `ign-msgs` and `ign-transport`

Overview

Python Ignition

This project aims to provide Python bindings for ignition-msgs and ignition-transport. It is a work in progress...

C++ and Python libraries for ignition-msgs are generated using Protobuf and gRPC rules for Bazel.

The objective is to generate Python bindings for ignition-transport using pybind11. Interoperability between native Python protobuf libraries and the C++ protobuf library used in the pybind11 extension module is provided by pybind11_protobuf.

Status

  • Working bindings for a selection of ignition-msgs are available using the protocol buffers native Python implementation. The build rules for the C++ implementation are also available however there is an open issue in pybind11_protobuf that prevents full interoperability in this case (see Notes below).
  • Bindings for ignition-transport are in development. A mock-up of the main interfaces is provided that illustrates the proposed approach.

Install: macOS

Install Bazel and the Google protocol buffers compiler using brew:

$ brew install bazel protobuf

Check the installed versions (protobuf must be version 3.19):

$ protoc --version
libprotoc 3.19.1

$ bazel --version
bazel 4.2.2-homebrew

Build everything

$ bazel build //...

Usage

The Bazel build file ign-msgs8=9.BUILD defines targets for a selection of messages. For example the targets for proto/ignition/msgs/time.proto are:

# proto_library
@ign-msgs9//:time_proto

# cpp_proto_library
@ign-msgs9//:time_cc_proto

# python_proto_library
@ign-msgs9//:time_py_pb2

C++

To use the bindings in C++:

// main.cc
#include "ignition/msgs/time.pb.h"
#include <iostream>

int main(int argc, const char* argv[])
{
  ignition::msgs::Time msg;
  msg.set_sec(11);
  msg.set_nsec(25);
  std::cout << msg.DebugString();
  
  return 0;
}
# BUILD.bazel
cc_binary(
  name = "main",
  srcs = ["main.cc"],
  deps = [
      "@ign-msgs9//:time_cc_proto",
  ],
)

Python

To use the bindings in Python:

# example.py
from ignition.msgs.time_pb2 import Time

msg = Time()
msg.sec = 15
msg.nsec = 21
print(msg)
# BUILD.bazel

py_binary(
  name = "example",
  srcs = ["example.py"],
  data = [
    "@com_google_protobuf//:proto_api",
  ],
  deps = [
    "@ign-msgs9//:time_py_pb2",
  ],
)

Examples

There are C++ and Python examples:

  • src/main.cc an example using the C++ protobuf library.
  • python/ign_proto_example an example using the Python protobuf library.
  • python/ign_msgs_example an example using the Python protobuf library and a simple extenson module with functions that accept and return ignition-msgs.
  • python/ign_transport_example an example using the Python protobuf library and an extenson module with a mock-up of the ignition.transport::Node interface.

Notes and Issues

protoc version

This version uses protoc version 3.19.1. You must ensure that the version of protoc installed by brew matches (otherwise the examples will segfault).

$ protoc --version
libprotoc 3.19.1

Protobuf generated Python libraries

There are some issues when using the C++ implementation of the generated Python protobuf library. The brew installation of protobuf will default to use the C++ implementation, to enable the Python implementation set the environment variable

export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python

before building the project.

Comments
  • Update CMake build to generate Python protobuf bindings

    Update CMake build to generate Python protobuf bindings

    This PR adds a step to compile the ign-msgs protobufs for Python.

    The CMake rule for generating the Python bindings is adapted from https://github.com/ignitionrobotics/ign-msgs/blob/main/src/CMakeLists.txt. An option is added to call protoc --python_out and custom targets are introduced to ensure the custom command is called.

    The Python bindings are output to the build directory ${PROJECT_BINARY_DIR}/python/ignition/msgs/<type>_pb2.py

    To use them include ${PROJECT_BINARY_DIR}/python in the PYTHONPATH

    export PYTHONPATH=$PYTHONPATH:${PROJECT_BINARY_DIR}/python
    

    The bindings may then be imported in Python as:

    from ignition/msgs/<type>_pb2 import <Type>
    
    opened by srmainwaring 1
  • Support more than one version of Ignition

    Support more than one version of Ignition

    This PR adds support for more than one version of Ignition

    Use the approach taken in ign-rviz which introduces the environment variable IGNITION_VERSION to set the Ignition release and determine which versions of ignition libraries to use.

    There is also an update to the pybind11_protobuf submodule that support builds on Linux/Ubuntu.

    opened by srmainwaring 0
  • Add bindings for services

    Add bindings for services

    This PR adds bindings for some of the ignition-transport service functions

    • List services
    • Provide service info
    • Call a service with a blocking request

    There are also some other maintenance changes

    • Rename the cmake project to python-ignition so it appears correctly in colcon graph
    • Update dependency on math to ignition-math7 (garden)
    • Update README with examples
    • Add docstrings to the bound functions and classes
    • Add bindings for dependencies (AdvertiseOptions and ServicePublisher etc.)
    enhancement 
    opened by srmainwaring 0
  • Align project structure with conventions for Python extensions used in ign-gazebo

    Align project structure with conventions for Python extensions used in ign-gazebo

    This PR restructures the pybind11 extension modules to better align with the conventions used in ign-gazebo

    Interface changes

    These changes alter the Python interface at the top level of import.

    The import for ign-transport was

    from ignition_transport import Node
    

    and is now

    from ignition.transport import Node
    

    The example module for messages was

    from ignition_msgs import make_time
    

    and is now

    from ignition.msgs.extras import make_time
    

    The protobuf bindings are unchanged.

    Bazel build changes

    The Bazel build has been overhauled so that the extension modules are organised into the correct hierarchy. The Python examples will now run without any need to set the PYTHONPATH or modify the import prefix.

    opened by srmainwaring 0
  • Update README and examples for CMake build

    Update README and examples for CMake build

    This PR updates the documentation and examples to focus on the CMake build

    • Update the README to prioritise the building and using the examples with a CMake build
    • Remove protobuf from submodules
    • Remove unused comments and dependencies from CMakeLists.txt
    • Minor updates to some examples
    opened by srmainwaring 0
  • Add CMake build to generate Python bindings for ign-msgs

    Add CMake build to generate Python bindings for ign-msgs

    The Python bindings for ign-msgs are generated in the Bazel build via the build file ign-msgs9.BUILD. There is currently no equivalent for the CMake build.

    The bindings are required for any of the Python examples that import an ignition messages using statements like:

    from ignition.msgs.pose_pb2 import Pose
    
    enhancement 
    opened by srmainwaring 0
  • Add CMake build for macOS

    Add CMake build for macOS

    This PR provides an initial CMake build for macOS

    Upstream dependencies

    • There is an upstream dependency on CMake support for pybind11_protobuf. The submodule references a fork https://github.com/srmainwaring/pybind11_protobuf/tree/feature/cmake that has a CMake build.

    Details

    • CMakeLists.txt is updated to include the same targets as the Bazel build.
    • The Python shebangs are corrected and files are made executable
    opened by srmainwaring 0
  • Remove python_ignition prefix from the ign_transport module imports

    Remove python_ignition prefix from the ign_transport module imports

    This PR changes the import statement for the module ign_transport in the Python examples

    For CMake builds the module is not prefixed by the project name, and the requirement to include the python_ignition prefix is an artefact of the Bazel build.

    The README contains instructions for setting the PYTHONPATH to allow the use of either build method.

    opened by srmainwaring 0
  • Add Bazel build for macOS

    Add Bazel build for macOS

    This PR enables the project to be built using Bazel.

    Bindings for ign-msgs and ign-transport can be built using Bazel and the rules for Ignition contained in the ign-bazel project.

    The Python module exposes the publish and subscribe interfaces of ignition::transport::Node and interfaces for supporting classes such as SubscribeOptions.

    The CMake build for the bindings has been temporarily disabled as the CMakeList.txt for dependencies is not complete now that the mock-up has been replaced with ign-transport.

    Python and C++ examples are provided that demonstrate how to use the bindings.

    opened by srmainwaring 0
  • Add bindings for ign-msgs and a mock-up of ign-transport

    Add bindings for ign-msgs and a mock-up of ign-transport

    Add simple protobuf example and generate bindings

    • Generate bindings for Python and C++
    • For C++ compile the bindings into a library
    • Provide example programs for C++ and Python

    Add example using pybind11_protobuf

    • Add external dependency on pybind11_protobuf
    • Add simple C++ example with functions accepting protobuf messages
    • Add pybind11 bindings
    • Update python test example

    Update pybind11_protobuf example

    • Move functions using the time.proto to separate library
    • Add example to main.cc
    • Update the pybind11_protobuf submodule version

    Disable the ignition_msgs test

    • This test broken as ignition_msgs is missing a dependency from pybind11_protobuf

    Rename the extension module to py_time_utils

    Add test example from pybind11_protobuf

    Update submodule for pybind11_protobuf

    Remove unused protos

    Add Bazel build files

    • Add support for building with Bazel
    • Update the python examples
    • Add external protobuf patch required in pybind11_protobuf

    Refactor time.proto -> time2.proto

    • Rename example time.proto in preparation for building ignition_msgs
    • Add dependency to ignition repos in workspace

    Build protobuf bindings for a sample of ignition.msgs

    • Add external build file for ignition-msgs
    • Add python example binary to verify python protobuf bindings

    Add ignition.msgs.pose

    Add license

    Add further ignition-msgs types

    • Add cmd_vel2d, double, double_vm float, float_v
    • Fix deps for pose_proto

    Add message types

    • Add message types for pid, twist, wrench, publish, publisher, subscribe. topic_info
    • Add basic checks in python module

    Add test module for ignition messages

    Update README and add further module examples

    • Add pybind11 examples for wrench and topic_info

    Clean up project

    • Leave only the ignition-msgs bindings and examples

    Add .gitignore

    Partial fix to cmake build

    Clean up

    • Remove unused header file
    • Add license to cpp files
    • Correct workspace name

    Add placeholder for ignition-transport bindings

    Add mock-up for ignition-transport Node

    Refactor - rename msg module to align with transport

    • Rename example module for ignition messages
    • Rename python example scripts

    Add mock-up for advertising topics

    Initial draft of subscribe mock-up (callbacks)

    Further additions to the subscribe mock-up

    Rename ignition-msgs9 -> ign-msgs9

    Enable use_fast_cpp_proto for Python bindings

    • Add flag to .bazelrc (set to false though as there is still an unresolved issue with isinstance for the C++ implementation)
    • Update C++ targets to use includes instead of copts
    • Update ign-msgs9.BUILD to use Python protobuf rules from https://rules-proto-grpc.com
    • Update version of pybind11_protobuf
    • Update ign_msgs_example to highlight issue

    Update README and examples

    • Update README with install instructions and more detail about the examples
    • Disable the failing case in ign_msgs_example.py
    • Output the msg debug string to std::cout

    Signed-off-by: Rhys Mainwaring [email protected]

    opened by srmainwaring 0
  • Support Ubuntu 20.04 Ignition Fortress

    Support Ubuntu 20.04 Ignition Fortress

    The build instructions currently only work on macOS Big Sur 11.6.1 for a source install of Ignition Garden

    The following changes are required to support Ubuntu 20.04 with Ignition Fortress

    1. pybind11_protobuf depends on a later version of protobuf than available on Ubuntu 20.04 (3.6)

    To upgrade the version of protoc:

    git clone https://github.com/google/protobuf.git
    cd protobuf/
    git submodule update --init --recursive
    ./autogen.sh 
    ./configure 
    make -j4
    make check
    sudo make install 
    sudo ldconfig
    
    $ protoc --version
    libprotoc 3.19.1
    
    1. CMake changes
    • The top level CMakeLists.txt needs to set set(CMAKE_CXX_FLAGS "-fPIC") to fix a link error in the abseil-cpp library.
    • For Ignition Fortress we need ign-msgs8 and ign-transport11
    • There is a link issue when building a shared library for pybind11_native_proto_caster. Converting this to a static library resolves the issue, but there should be a better solution.
    1. The ignition libraries will need to be built (clean) from source to ensure that consistent versions of protobuf are used throughout.
    enhancement 
    opened by srmainwaring 0
  • Some message types not discovered in Bazel build

    Some message types not discovered in Bazel build

    Some message types are not discovered when published using the Bazel build. This is not particular to Python, but also occurs for the C++ examples (so it does not appear to be a binding issue).

    How to replicate

    From terminal 1 run the C++ rover_publisher:

    $ ./bazel-bin/python_ignition/rover_publisher
    Publishing pose on topic [/pose], twist on topic [/twist]
    Publishing pose on topic [/pose], twist on topic [/twist]
    ...
    

    From terminal 2 run the C++ ign_topic_echo subscribing to /pose:

    $ /bazel-bin/python_ignition/ign_topic_echo -t /pose 
    header {
      stamp {
        sec: 4
        nsec: 513947250
      }
    }
    name: "base_link"
    id: 9
    position {
      x: 4.6053049700144255
      y: 1.9470917115432527
    }
    orientation {
      z: 0.19866933079506122
      w: 0.98006657784124163
    }
    ...
    

    From terminal 2 run the C++ ign_topic_echo subscribing to /twist:

    $ /bazel-bin/python_ignition/ign_topic_echo -t /twist
    

    In the second case no messages are displayed for the type ignition.msgs.Twist


    Using the Python tools we can verify that both messages are published:

    $ ./bazel-bin/python_ignition/python/ign_topic_list  
    /pose
    /twist
    
    $ ./bazel-bin/python_ignition/python/ign_topic_info -t /pose
    Publishers [Address, Message Type]:
      tcp://192.168.1.31:62260, ignition.msgs.Pose
    
    $ ./bazel-bin/python_ignition/python/ign_topic_info -t /twist
    Publishers [Address, Message Type]:
      tcp://192.168.1.31:62260, ignition.msgs.Twist
    

    The issue is apparent with other messages types as can be seen by using the multi-message publisher:

    From terminal 1:

    $ ./bazel-bin/python_ignition/python/pub_all_msg_types
    

    From terminal 2:

    $ ./bazel-bin/python_ignition/python/ign_topic_list
    /cmd_vel
    /double
    /double_v
    /float
    /float_v
    /header
    /pid
    /pose
    /publish
    /quat
    /subscribe
    /time
    /topic_info
    /twist
    /vector3d
    /wrench
    

    and then checking each topic in turn:

    # working
    $ ./bazel-bin/python_ignition/ign_topic_echo -t /double
    header {
      stamp {
        sec: 15
        nsec: 21
      }
    }
    data: 10
    ...
    
    # not working
    $ ./bazel-bin/python_ignition/ign_topic_echo -t /double_v
    

    The issue does not occur when running the examples built using the CMake build.

    bug 
    opened by srmainwaring 0
Owner
Rhys Mainwaring
Rhys Mainwaring
A new mini-batch framework for optimal transport in deep generative models, deep domain adaptation, approximate Bayesian computation, color transfer, and gradient flow.

BoMb-OT Python3 implementation of the papers On Transportation of Mini-batches: A Hierarchical Approach and Improving Mini-batch Optimal Transport via

Khai Ba Nguyen 18 Nov 14, 2022
pvaPy provides Python bindings for EPICS pvAccess

PvaPy - PvAccess for Python The PvaPy package is a Python API for EPICS7. It supports both PVA and CA providers, all standard EPICS7 types (structures

EPICS Base 25 Dec 5, 2022
Low-level Python CFFI Bindings for Argon2

Low-level Python CFFI Bindings for Argon2 argon2-cffi-bindings provides low-level CFFI bindings to the Argon2 password hashing algorithm including a v

Hynek Schlawack 4 Dec 15, 2022
Python bindings for the Plex API.

Python-PlexAPI Overview Unofficial Python bindings for the Plex API. Our goal is to match all capabilities of the official Plex Web Client. A few of t

Michael Shepanski 931 Jan 7, 2023
Python bindings for Basler's VisualApplets TCL script generation

About visualapplets.py The Basler AG company provides a TCL scripting engine to automatize the creation of VisualApplets designs (a former Silicon Sof

Jürgen Hock 2 Dec 7, 2022
High-level bindings to the Valhalla framework.

Valhalla for Python This spin-off project simply offers improved Python bindings to the fantastic Valhalla project. Installation pip install valhalla

GIS • OPS 20 Dec 13, 2022
Run python scripts and pass data between multiple python and node processes using this npm module

Run python scripts and pass data between multiple python and node processes using this npm module. process-communication has a event based architecture for interacting with python data and errors inside nodejs.

Tyler Laceby 2 Aug 6, 2021
Data Structures and Algorithms Python - Practice data structures and algorithms in python with few small projects

Data Structures and Algorithms All the essential resources and template code nee

Hesham 13 Dec 1, 2022
Built with Python programming language and QT library and Guess the number in three easy, medium and hard rolls

guess-the-numbers Built with Python programming language and QT library and Guess the number in three easy, medium and hard rolls Number guessing game

Amir Hussein Sharifnezhad 5 Oct 9, 2021
Built with Python programming language and QT library and Guess the number in three easy, medium and hard rolls

password-generator Built with Python programming language and QT library and Guess the number in three easy, medium and hard rolls Password generator

Amir Hussein Sharifnezhad 3 Oct 9, 2021
Cirq is a Python library for writing, manipulating, and optimizing quantum circuits and running them against quantum computers and simulators

Cirq is a Python library for writing, manipulating, and optimizing quantum circuits and running them against quantum computers and simulators. Install

quantumlib 3.6k Jan 7, 2023
A simple script written using symbolic python that takes as input a desired metric and automatically calculates and outputs the Christoffel Pseudo-Tensor, Riemann Curvature Tensor, Ricci Tensor, Scalar Curvature and the Kretschmann Scalar

A simple script written using symbolic python that takes as input a desired metric and automatically calculates and outputs the Christoffel Pseudo-Tensor, Riemann Curvature Tensor, Ricci Tensor, Scalar Curvature and the Kretschmann Scalar

null 2 Nov 27, 2021
An awesome list of AI for art and design - resources, and popular datasets and how we may apply computer vision tasks to art and design.

Awesome AI for Art & Design An awesome list of AI for art and design - resources, and popular datasets and how we may apply computer vision tasks to a

Margaret Maynard-Reid 20 Dec 21, 2022
Izy - Python functions and classes that make python even easier than it is

izy Python functions and classes that make it even easier! You will wonder why t

null 5 Jul 4, 2022
Msgpack serialization/deserialization library for Python, written in Rust using PyO3 and rust-msgpack. Reboot of orjson. msgpack.org[Python]

ormsgpack ormsgpack is a fast msgpack library for Python. It is a fork/reboot of orjson It serializes faster than msgpack-python and deserializes a bi

Aviram Hassan 139 Dec 30, 2022
PyPIContents is an application that generates a Module Index from the Python Package Index (PyPI) and also from various versions of the Python Standard Library.

PyPIContents is an application that generates a Module Index from the Python Package Index (PyPI) and also from various versions of the Python Standar

Collage Labs 10 Nov 19, 2022
Minutaria is a basic educational Python timer used to learn python and software testing libraries.

minutaria minutaria is a basic educational Python timer. The project is educational, it aims to teach myself programming, python programming, python's

null 1 Jul 16, 2021
The purpose is to have a fairly simple python assignment that introduces the basic features and tools of python

This repository contains the code for the python introduction lab. The purpose is to have a fairly simple python assignment that introduces the basic

null 1 Jan 24, 2022
ArinjoyTheDev 1 Jul 17, 2022