Open FirefoxMetzger opened 3 years ago
Great work on ropy
so far!
One thought is that we could either expose a C API for doing a CPython-style wrapper. Alternatively, ROS2 has been moving forward with using pybind11
as a wrapper.
Adding a python api natively to transport could help reduce some wheel reinvention.
Great work on ropy so far!
Thanks! Glad to hear you like it 😄
Adding a python api natively to transport could help reduce some wheel reinvention.
I agree that it would be very nice to not have to reinvent the wheel unnecessarily. What I am less clear about is how to accomplish that. I seem to just see obstacles everywhere. Here are some thoughts:
await
-able call to keep the simulation in sync and account for network/transport delays after each simulation step. ropy.ignition.Subscriber.recv(blocking=True)
does just that. Here is a related comment and the comments above are partly on this topic. Unfortunately, this isn't possible via the current ign-transport API, but I guess it could be added? However, if you combine gym-ignition (to control the main loop) and ropy (for message passing) you can do just that.On the topic of generated bindings (swig
and to some extent pybind11
) there are two drawbacks:
ropy.ignition.Subscriber
implements a context manager, so you can use with ign.Subscriber(...) as topic:
and have guaranteed cleanup. The same QoL applies to the interface in general. The generated API will always have a C++ feel with signatures that may be unintuitive in a language that isn't C++, cryptic error messages, and/or bad exception handling. gym-ignition (a really awesome library) is a good example here (uses swig bindings around a C++ API). You end up having to do something like assert model.to_gazebo().reset_base_world_linear_velocity(scenario_core.Array3d(velocity.tolist()))
for something that should really be model.base_velocity = velocity
(and fails with an Exception instead of True/False) in python.Another option is to write a python wrapper by hand with meaningful signatures and docstrings, which then calls the C++ API under the hood. Many big python libraries do this (pytorch/torch, tensorflow, pyzmq, numpy, scipy) and this effectively deals with the two drawbacks of an automatically wrapped library. In general, this is a very nice approach and if Ignition goes down that road I'll probably end up helping out in some form. For ign-transport specifically, I think it may be easier to speak just speak the same protocol on the wire and use I/O as the natural boundary between languages. It just seems like less work given that we have pyzmq
and betterproto
which make communicating with Ignition quite pythonic already. For this to work, what is missing is node discovery, but that is mainly due to a lack of understanding on my part.
Ignition uses
ign-transport
to communicate between different parts of the library, and we can introspect this communication usingropy.Subscriber
.Under the hood, this uses a mix of zmq and the ignition CLI (via
subprocess
) to make itself known to ignition and to start receiving messages. The main reason why this isn't implemented cleaner is that I didn't find documentation on how topic discovery works in ignition. However, there appears to be some documentation (living here) that describes how ignition passes messages around to discover topics.A great addition would be to implement this discovery protocol here, so that we can cleanly interface with Ignition.
Possible related issue: https://github.com/ignitionrobotics/ign-transport/issues/225