SofaDefrost / SoftRobots.Inverse

Other
8 stars 8 forks source link

[binding] QPInverseProblemSolver: adds python binding #24

Closed EulalieCoevoet closed 4 months ago

EulalieCoevoet commented 5 months ago

Usage example:

import Sofa.SoftRobotsInverse

class MyQPInverseProblemSolver(Sofa.SoftRobotsInverse.QPInverseProblemSolver):

    def __init__(self, *args, **kwargs):
        Sofa.SoftRobotsInverse.QPInverseProblemSolver.__init__(self, *args, **kwargs)

    def solveSystem(self):
        W = self.W()
        dfree = self.dfree()
        forces = self.lambda_force()  # pointer on lambda
        [...] # solve the problem and store the result in forces
        return True

def createScene(rootnode):
    rootnode.addObject(MyQPInverseProblemSolver)
    [...]
damienmarchal commented 5 months ago

I gave it a quick look and seems ok.

alxbilger commented 5 months ago

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?

EulalieCoevoet commented 5 months ago

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). 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
alxbilger commented 5 months ago

I am considering adding a trampoline class for ConstraintSolverImpl, not only for QPInverseProblemSolver. I see that your version needs specific data from QPInverseProblemSolver in storeResults. Would it be required to write its own storeResults for ConstraintSolverImpl?