Hey folks, so python bindings for Gazebo are something I’ve considered for a long time now. Usually this comes up in the context of I have a ros python node that I want to interact with gazebo transport, but just recently I had another case where I have python scripts that I want to spin up and manage many instances of gazebo simulations and having bindings would be much better than using the subprocess module. A third possible motivation would be making it easier to teach people how to use the gazebo APIs.
I’ve been using pybind11 recently for some of my own C++ code and it’s quite simple to use.
I’m wondering if there are enough use cases or general interest in this? Has this been discussed at all within Open Robotics?
1 Like
A ruby interface using swig was added to ignition-math:
I think we could add a python interface in a similar way?
This is something we are interested in but haven’t been actively pursuing at the moment.
I don’t have any experience with tools that do it automatically (swig?) but I wouldn’t be surprised if they existed for python too. My approach has been to expose whatever I need to expose by hand. OMPL I believe generates all the bindings automatically so that could be a thing to look at.
I know Nate really likes Ruby, but I’ve always felt it was a weird choice since I’ve never heard of it used for anything in robotics. Do you know of anyone outside of open robotics using the Ruby bindings or expressing interest in them?
I believe swig supports python too, so I think the same approach that we’ve used for ruby could work for python too.
I am looking forward to having official ignition bindings, it would be really a great addition. Using external processes with transport is a sound solution, but many application might be limited if they have to rely to socket-based connections.
I have recently worked towards this direction for a project I’m developing and I can share my experience. Swig is one of the only mature solution that provide multiple languages support, and it was the natural choice despite I only currently need Python. I didn’t face many issues in the process, but instead of binding directly the Ignition Gazebo public APIs, I wrapped the simulator in a C++ wrapper, and then exposed the wrapper to Python with Swig. In this way I could configure the simulator in C++ using its native language and then expose to Python only a very high-level interface. This choice was also related to the fact that Ignition uses heavily C++17 and there is no support of this standard in Swig (e.g. std::optional, widely used in ignition robotics). I don’t think is very demanding developing new typemaps for the missing features, but it goes beyond the scope of my work for the time being.
If you want to have a look to the development status and have an example from where to start, have a look to robotology/gym-ignition, and particularly GazeboWrapper.
I’m not sure if it’s the thing you need, but I’m maintaining a small library for my project here: https://github.com/ci-group/pygazebo/tree/py2to3 (py2to3 branch)
it’s a library to communicate with gazebo via protobuf messages. It’s rough and I would like to improve it, but it works.
One of the main use cases I have is running a number of gazebo instances, and so I would actually want the ability to start gzserver/gzclient executables, manage them, etc… so just a messaing API would not quite do it for that scenario. But still a useful thing to have. Like Diego said, making bindings for ignition/gazebo would be the more complete solution.
Another project that might be quite interesting as a Swig alternative is Microsoft/xlang (FAQ). I do not have direct experience with it nor I saw in the past any real example, but it definitely worth a look.
Considering classic gazebo and ignition transport, I remember I read that the developers of gym-gazebo2 (paper) claim they have network segmentation to allow multiple simulator instances. I do not know exactly how port names are affected by it, but @portaloffreedom library might be useful in this setup if it can interface smoothly with it.
1 - I confirm that I’m actually running multiple instances gazebo at the same time, being able to communicate to them from the same python script at the same time.
2 - I just update the library to use python3 and asyncio, for clearer and more modern code. https://github.com/ci-group/pygazebo (master branch)
@portaloffreedom Nice work. Bwt for readers not very familiar with Gazebo I would like to point out that your library will not work (yet?) with Ignition Gazebo as the OP was asking.
For a very simple example on Ignition Gazebo you can refer to joint_controller.sdf.
I’m looking into using pybind11_protobuf
to allow native Python bindings generated from the ign-msgs
protobufs to be used with pybind11
extensions to ign-transport
. The aim is to have the core ignition::transort::Node
features available in Python (i.e. publish and subscribe to topics).
Progress so far is available here: GitHub - srmainwaring/python-ignition: Python bindings for `ign-msgs` and `ign-transport`. The Python / C++ interop is working for a selection of ign-msgs
and there’s a mocked-up sketch of the extension for ign-transport
. At present it is all built with Bazel as that’s the build system available for pybind11_protobuf
, but the intention would be to port it all over to cmake
when it’s working.
Next steps are to get a Bazel build of the ignition libraries using ign-bazel
and wire up the interface to the actual libraries. Getting the subscriptions to work correctly will be the challenging part of the project, and any thoughts / help on that welcomed.
2 Likes
A follow-up on Python bindings for ign-msgs
and ign-transport
using pybind11
.
There is an experimental version tested on macOS integrated with the main branches of ign-msgs
and ign-transport
. There are both Bazel and CMake builds available - I’d recommend the CMake build as it generates bindings for all messages and there is an odd issue with some message types not latching in the subscribe callback in the Bazel build.
The bindings let you write this type of thing in Python:
import time
import typing
from ignition.msgs.stringmsg_pb2 import StringMsg
from ignition_transport import SubscribeOptions
from ignition_transport import Node
def cb(msg: StringMsg) -> None:
print("Msg: [{}] from Python".format(msg.data))
def main():
# create a transport node
node = Node()
topic = "/foo"
msg_type_name = StringMsg.DESCRIPTOR.full_name
sub_options = SubscribeOptions()
# subscribe to a topic by registering a callback
if node.subscribe(topic, cb, msg_type_name, sub_options):
print("Subscribing to type {} on topic [{}]".format(
msg_type_name, topic))
else:
print("Error subscribing to topic [{}]".format(topic))
return
# wait for shutdown
try:
while True:
time.sleep(0.001)
except KeyboardInterrupt:
pass
if __name__ == "__main__":
main()
So far only the publish and subscribe interfaces of ignition::transport::Node are exposed, but it should be straightforward to add the service interface if required.
2 Likes
is the Python bindings only supported on gz-transport 13?
There are more python bindings aside from gz-transport13. Probably not easy to found in documentation so you can check your system using:
$ apt-cache search ‘python3-gz|python3-sdformat’
Some of have tutorials or documentation. A search in the gazebo_test_cases repository (used for release tutorial parties) on Harmonic and python can point to some of these: Issues · gazebosim/gazebo_test_cases · GitHub
You can also find examples and test directly in the code inside each of the repositories python* directories. The gz-math one gz-transport/python at gz-transport13 · gazebosim/gz-transport · GitHub.
Hope it helps.
P.D: I created a PR for my personal gazebo-doc-index so it helps other people to find this kind of information. Include a section on programming by j-rivero · Pull Request #1 · j-rivero/gazebo-doc-index · GitHub
Thanks for reply
I have inspected the source code for gz-transport12 but I dont see any python support or example like which you have linked in gz-transport13
I only see support for ruby in gz-transport12.
Im building gz-transport12 from source, and i cant find any python files being generated in the build directory.
find ./ -iname "*.py"
Any other tips would be appreciated, but I am still investigating.
You don’t need to investigate more
The python bindings were implemented in the version 13 of gz-transport, as you can see in the Changelog.
1 Like