nphysics
nphysics copied to clipboard
Support for different solvers and dynamic switching between them
Currently, only one constraint solver is available and implemented in the MoreauJeanSolver struct. For research purposes I'm working on other constraint solver implementations (though they are far too specialized at the moment to contribute them anytime soon). At the moment there is no simple way of implementing and switching between different solvers in nphysics without forking it and implementing everything inside of the fork.
First of all, I would propose to add a ConstraintSolver trait that requires all functions that are currently called on the MoreauJeanSolver by the MechanicalWorld or should be part of the solver interface in general. This includes at least the functions step and step_ccd. It might also include the set_contact_model function but I'm not 100% sure if this has to be required for the trait.
The second point would be how different solver types get handled by the world. This could be done either through generics or using a trait object.
The first approach would be easier to combine with the current design of the MechanicalWorld and its methods. I think this would just require to add a generic Solver: ConstraintSolver parameter to the world and accordingly change the type of the solver field. This should be enough to make it work.
Alternatively, one could also use a trait object to access the solver. This would technically allow changing the solver between steps without constructing a new MechanicalWorld.
However this requires more changes from the current design.
- The method
stepof theMechanicalWorldand the methodsstepandstep_ccdalong with some internal methods ofMoreauJeanSolverare generic wrt.Colliders: ColliderSet<N, Bodies::Handle, Handle = CollHandle>andConstraints: JointConstraintSet<N, Bodies>. They have to be removed from the methods to support creating aContstraintSolvertrait object. The only possible solution I can think of is moving the generic parameters to theConstraintSolverandMechanicalWorldtraits themselves. Inside of the constraint solver implementations this would require adding phantom data fields because the types are only used be the respective methods. - Changing the solver to a trait object requires adding an additional lifetime bound of
`staticto some of its generic parameters which includesBodies,CollidersandConstraint. I'm not sure if this is ok because I think a goal of making these set types generic parameters was to move lifetime handling out of the world.
Any thoughts on this?