How to access the contact forces when using constraint resolution based on Lagrange multipliers #3812
Replies: 4 comments
-
|
Thanks Hugo! Much appreciated. |
Beta Was this translation helpful? Give feedback.
-
|
Please note a major update in the above explanation @oystebje In short. Resulting from the constraint resolution, this data |
Beta Was this translation helpful? Give feedback.
-
|
To get a more generic script not only working with rigid but with deformable bodies also, see #4415 |
Beta Was this translation helpful? Give feedback.
-
|
For your information, I just created an example as a PR in the SofaPython3 repository describing how to easily access (and visualize) contact forces, when using the response method "FrictionContactConstraint". See ➡️ https://github.com/sofa-framework/SofaPython3/pull/514/files |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Further to several discussions ( #2871 #3228 #3275 ), it appeared that a summary on "how to access contact forces when using constraint resolution based on Lagrange multipliers" was necessary.
Context
This post therefore addresses the case of collision solved as a constraint problem. When solving constraints (here we address the case of contacts) using the Lagrange multipliers, your SOFA scene should contain:
FreeMotionAnimationLoopLCPConstraintSolverorGenericConstraintSolverDefaultContactManagerwith its dataresponse="FrictionContactConstraint"(handling both friction or frictionless contacts)In this context, let's detail how to access the contact forces.
Context
To do so, the ConstraintSolver you use (either
where
is the vector of constraint forces (contact forces in case of contacts) in the constraint space. In the case of frictional contacts in 3d, it means each contact force
is a vector of 3 values corresponding to the force intensities along the normal and the two tangential directions:
LCPConstraintSolverorGenericConstraintSolver) should define the datacomputeConstraintForces="1". This boolean data will activate the computation of aconstraintForcesdata. Resulting from the constraint resolution, this dataconstraintForcessaves the constraint impulse : the time stepInstead, what most of the users are interested in are the contact forces
expressed in the world coordinates (x,yz):
To compute these forces, we need to compute the back-transformation from the constraint space towards the world coordinate space :

where
is the constraint Jacobian matrix containing the constraint directions, i.e. the contact directions. This matrix is the Jacobian of the transformation between the world coordinate system and the constraint space. This constraint Jacobian matrix is available in a
constraintdata structure (C++ map of map) of the MechanicalObject of the collision model of your object.This map-map structure of the data
can be misleading.
constraintcorresponding toHere is an example:
The above data means that we have 3 constraints (3 lines), each of them affecting 2 degrees of freedom (nodes) of the collision model. These constraints correspond to frictional contacts since each constraint is a vector of 3 floating values (n, t1, t2). The structure of the
constraintdata field can be generalized as follows:Example with a python script
Click to expand the example 👇
If this helps you in getting the forces, please upvote this discussion using t he "up" ⬆️ button below.
@nhnhan92 @DanteAngio8 @noteddeh @@oystebje @camilla-agabiti @NotJed317 @satimmer @peyronq1 @BrunoB81HK
Cheers
Beta Was this translation helpful? Give feedback.
All reactions