-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Check if pybind11 can be used as an intermediate binding between MATLAB and Drake C++ #5981
Comments
It might be possible to do this with the custom type conversions in pybind11: http://pybind11.readthedocs.io/en/master/advanced/cast/custom.html although I haven't used that mechanism myself. |
i've merged my example: I view the mismatch between numpy arrays and matlab matrices to be much more of a burden than the occasional int32 cast. The most relevant discussion I found about it on a quick search yesterday is here: |
@rdeits Thanks! Will check into that. @RussTedrake Thanks for the link! Given that issue, I've set the priority to medium (had intended low originally). Please let me know if you'd like me to up the priority. In terms of timeline, do you have an idea of when would decide on how we should implement our MATLAB bindings? |
Based on today's slack poll, it looks like making the systems classes available in Python should be the first priority. If we can make those same bindings provide the solution for matlab, that would be ideal; otherwise we need to at least lay out an alternative plan for our matlab bindings. So -- I would say that spike testing syntactic solutions to support the numpy array <--> matlab array conversions would be medium priority simply to provide information for that road-mapping. Thanks! |
Simple Problem (accept
|
As a quick test, I fleshed out a variant of the options listed above, proxying Python objects via MATLAB Since MATLAB R2016b does not support converting 2D arrays to Python arrays, I've added in the I have added an example MATLAB script that takes in / modifies a
Code snippet: % scratch.py is a simple Python module
pyscratch = pyimport('scratch');
mscratch = PyProxy(pyscratch);
% Construct object
mlo = mscratch.Test('hello');
% Tinker with arrays
mlo.nparray = [5, 10, 15];
mlo.nparray(3) = 20; % Permitted - getter/setter combo in MATLAB permits natural indexing (but slow due to copies) Caveats:
Per a discussion with @avalenzu, I'll check to see if there are things in MATLAB that offer any better, more concrete mechanism to do this type-simplifying job. |
Just as a note: Scipy specifically recommends not using Since matrices mostly behave like |
Awesome, thanks for sharing! I've updated the above post. |
@rdeits -- to be clear, do you think we should bind the existing C++ interfaces taking Eigen matrices twice, once with numpy arrays and once with C++ double arrays. Is that something that we could do relatively cleanly with pybind11, and without cluttering the python drake namespace? |
Er, no. We should just bind them to take and return numpy arrays. I don't think there's any reason to have C++ double arrays around on the Python side. |
I'm sorry... I didn't read carefully enough. What I meant is that we bind both numpy.matrix and numpy.ndarray? Or is ndarray an acceptable replacement for a python-only workflow? |
No, the scipy docs suggest that we don't use |
I've taken another crack at updating some of the MATLAB - Python stuff. Didn't know how comprehensive I've updated the readme: repro/bindings/README.md
|
The redux looks very promising! |
Checked on the following items with MathWorks regarding MATLAB (R2017a as of the time of this writing):
We have an easy workaround to 1, though we should stress test it. Item 2 may be a bit of a blocker, as that would prevent meaningful System authoring from MATLAB. Possible workarounds:
|
For (2), i think that we can write a matlab-specific leafsystem class in c++ that takes only the string of the matlab classfile name in the constructor, then calls mexCallMATLAB to call into matlab directly (obviously this c++ code will need to link against the matlab libraries). That is essentially how the "matlab-only" workflow (which actually ran through a c++ s-function) worked before: |
Looks awesome! I may have a simple setup, which builds on top of how This means that we could call any MATLAB method from Python from C++ with only about ~100 lines extra. Then the virtual inheritance could come from generating a MATLAB base class on the fly using Python's reflection (my guess is ~200 lines) to handle which methods are actually virtual, in a generic fashion, such that a user could then use the intended base class with minimal API duplication on our part (just relying on the pybind11 bindings to guide everything). I am aiming to have a simple prototype of calling a MATLAB method from Python in a few hours, and will post back if/when I get it working. |
Here's a simple prototype of the above setup working, albeit still dirty:
NOTE: Only tested on my system (Ubuntu 16.04, MATLAB R2016b) Cons:
Pros:
Given that this is a concrete but hacky solution, I will use this to ask for better ways to do this. |
Given that there are prototype solutions of MATLAB-ifying Python w.r.t. pybind (scalar and int/double overloads), and given this is a spike test, I will say this is complete. The conclusion is yes, C++ -> pybind -> Python -> custom PyProxy -> MATLAB should be sufficient for basic offerings. |
UPDATE: The scope of this has been expanded to check if we can MATLAB bindings "for free" using
pybind11
and MATLAB's Python support, with some extra shims on top.ORIGINAL: This is issue is to figure out if there is a way to relax
pybind11
s constraints on passed types, such as a custom marshaling mechanism on integral types, to accept floating-point values when bound to C-type integral types. If this is possible, then we can check to see if we can do a small run-time check toround
it to the correct value if within an acceptableeps
.This would permit using the bindings in a more natural fashion within MATLAB, if the
pybind11
bindings overall play well with MATLAB and could be used either directly, or within a wrapper.If it could be used directly, then we could do something like from Russ's PR test program:
(could figure out if there is a way to fudge this with
import
statements, or useevalin('caller', ...)
for consistent usage in MATLAB code.)This would permit more natural syntax, where in general MATLAB permits floating-point values as size arguments (such as
zeros(n)
, etc.).The alternative is to write wrappers, which is certainly doable, but may be burdensome if we could end up just writing aliases.
\cc @RussTedrake @rdeits
The text was updated successfully, but these errors were encountered: