-
Notifications
You must be signed in to change notification settings - Fork 8
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
[binding] QPInverseProblemSolver: adds python binding #24
Conversation
I gave it a quick look and seems ok. |
src/SoftRobots.Inverse/binding/Binding_QPInverseProblemSolver.cpp
Outdated
Show resolved
Hide resolved
s.def("W", [](QPInverseProblemSolver& self) -> EigenMatrixMap | ||
{ | ||
assert(self.getConstraintProblem()); | ||
auto& W_matrix = self.getConstraintProblem()->W; | ||
return { W_matrix.ptr(), W_matrix.rows(), W_matrix.cols()}; | ||
}); | ||
|
||
s.def("lambda_force", [](QPInverseProblemSolver& self) -> Eigen::Map<Eigen::Matrix<SReal, Eigen::Dynamic, 1> > | ||
{ | ||
assert(self.getConstraintProblem()); | ||
auto& lambda = self.getConstraintProblem()->f; | ||
return { lambda.ptr(), lambda.size()}; | ||
}); | ||
|
||
s.def("dfree", [](QPInverseProblemSolver& self) -> Eigen::Map<Eigen::Matrix<SReal, Eigen::Dynamic, 1> > | ||
{ | ||
assert(self.getConstraintProblem()); | ||
auto& dfree = self.getConstraintProblem()->dFree; | ||
return { dfree.ptr(), dfree.size()}; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder why you need this whereas there is already these bindings for ConstraintSolverImpl
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought the same, but I didn't find why it does not work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you elaborate a bit ? What is not working ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When used like that:
import Sofa.SoftRobotsInverse
import Sofa.SofaConstraintSolver
class MyQPInverseProblemSolver(Sofa.SoftRobotsInverse.QPInverseProblemSolver):
def __init__(self, emio, *args, **kwargs):
Sofa.SoftRobotsInverse.QPInverseProblemSolver.__init__(self, *args, **kwargs)
def solveSystem(self):
W = self.W()
dfree = self.dfree()
torques = self.lambda_force()
return True
The calls to W()
, dfree()
, and lambda_force()
do not work, meaning I get :
terminate called after throwing an instance of 'pybind11::error_already_set'
what(): AttributeError: Unable to find attribute: W
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not the expected behavior :)
What is the result of:
q = MyQPInverseProblemSolver(name="q")
print(dir(q)) # What is the content of q
print(type(q)) # And its type
# Adding the python object 'q' to c++ sofa...
root.addObject(q)
# And retrieve it from the rootNode (so converting it back to python)
q = rootNode.q
print(dir(q)) # What is the content of q
print(type(q)) # And its type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
['actuatorsOnly', 'allowSliding', 'bbox', 'componentState', 'countdown', 'displayTime', 'epsilon', 'info', 'listening', 'maxContactForces', 'maxIterations', 'minContactForces', 'multithreading', 'name', 'objective', 'printLog', 'responseFriction', 'reverseAccumulateOrder', 'saveMatrices', 'tags', 'tolerance']
<class 'lab2-inversekinematics.MyQPInverseProblemSolver'>
['actuatorsOnly', 'allowSliding', 'bbox', 'componentState', 'countdown', 'displayTime', 'epsilon', 'info', 'listening', 'maxContactForces', 'maxIterations', 'minContactForces', 'multithreading', 'name', 'objective', 'printLog', 'responseFriction', 'reverseAccumulateOrder', 'saveMatrices', 'tags', 'tolerance']
<class 'lab2-inversekinematics.MyQPInverseProblemSolver'>
src/SoftRobots.Inverse/binding/Binding_QPInverseProblemSolver.cpp
Outdated
Show resolved
Hide resolved
src/SoftRobots.Inverse/binding/Binding_QPInverseProblemSolver.cpp
Outdated
Show resolved
Hide resolved
src/SoftRobots.Inverse/binding/Binding_QPInverseProblemSolver.cpp
Outdated
Show resolved
Hide resolved
The unit test https://github.com/alxbilger/SofaPython3/blob/d16750f7fa6fe1075876877fc831f4d225ec9f90/bindings/Modules/tests/SofaConstraintSolver/matrix_access.py works for me with the following changes (without your PR): "Sofa.Component.Mapping.MappedMatrix",
"Sofa.Component.Mass",
"Sofa.Component.ODESolver.Backward",
- "Sofa.Component.Topology.Container.Dynamic"])
+ "Sofa.Component.Topology.Container.Dynamic",
+ "SoftRobots.Inverse"])
root.addObject("FreeMotionAnimationLoop", solveVelocityConstraintFirst=True)
- root.addObject("GenericConstraintSolver", name="constraint_solver", tolerance=1e-9, maxIterations=1000)
+ root.addObject("QPInverseProblemSolver", name="constraint_solver", tolerance=1e-9, maxIterations=1000)
root.addObject("StringMeshCreator", name="loader", resolution="20")
root.addObject("EulerImplicitSolver")
Could you check that you have the same result? |
Yes it works. What does not work is when used like that (without duplicating what you did in the module SofaConstraintSolver): import Sofa.SoftRobotsInverse
import Sofa.SofaConstraintSolver
class MyQPInverseProblemSolver(Sofa.SoftRobotsInverse.QPInverseProblemSolver):
def __init__(self, emio, *args, **kwargs):
Sofa.SoftRobotsInverse.QPInverseProblemSolver.__init__(self, *args, **kwargs)
def solveSystem(self):
W = self.W()
dfree = self.dfree()
torques = self.lambda_force()
return True |
src/SoftRobots.Inverse/binding/Binding_QPInverseProblemSolver.cpp
Outdated
Show resolved
Hide resolved
I am considering adding a trampoline class for |
Usage example: