add max split impulse push out distance and switch contact to be double sided

This commit is contained in:
Xuchen Han
2020-04-23 01:54:37 -07:00
parent bc8f99a640
commit 296602fc57
6 changed files with 37 additions and 33 deletions

View File

@@ -36,7 +36,7 @@ public:
btConjugateResidual(const int max_it_in)
: max_iterations(max_it_in)
{
tolerance_squared = 1e-2;
tolerance_squared = 1e-5;
}
virtual ~btConjugateResidual(){}
@@ -55,11 +55,6 @@ public:
r = z;
btScalar residual_norm = norm(r);
if (residual_norm <= tolerance_squared) {
if (verbose)
{
std::cout << "Iteration = 0" << std::endl;
std::cout << "Two norm of the residual = " << residual_norm << std::endl;
}
return 0;
}
p = r;
@@ -84,19 +79,8 @@ public:
best_x = x;
best_r = norm_r;
if (norm_r < tolerance_squared) {
if (verbose)
{
std::cout << "ConjugateResidual iterations " << k << std::endl;
}
return k;
}
else
{
if (verbose)
{
std::cout << "ConjugateResidual iterations " << k << " has residual "<< norm_r << std::endl;
}
}
}
// temp_r = A * r;
A.multiply(r, temp_r);
@@ -110,7 +94,7 @@ public:
}
if (verbose)
{
std::cout << "ConjugateResidual max iterations reached " << max_iterations << std::endl;
std::cout << "ConjugateResidual max iterations reached, residual = " << best_r << std::endl;
}
x = best_x;
return max_iterations;

View File

@@ -142,6 +142,7 @@ btDeformableRigidContactConstraint::btDeformableRigidContactConstraint(const btS
m_total_tangent_dv.setZero();
// The magnitude of penetration is the depth of penetration.
m_penetration = c.m_cti.m_offset;
m_total_split_impulse = 0;
// m_penetration = btMin(btScalar(0),c.m_cti.m_offset);
}
@@ -149,6 +150,7 @@ btDeformableRigidContactConstraint::btDeformableRigidContactConstraint(const btD
: m_contact(other.m_contact)
, btDeformableContactConstraint(other)
, m_penetration(other.m_penetration)
, m_total_split_impulse(other.m_total_split_impulse)
{
m_total_normal_dv = other.m_total_normal_dv;
m_total_tangent_dv = other.m_total_tangent_dv;
@@ -219,7 +221,11 @@ btScalar btDeformableRigidContactConstraint::solveConstraint(const btContactSolv
dn += m_penetration * infoGlobal.m_deformable_erp / infoGlobal.m_timeStep;
}
// dn is the normal component of velocity diffrerence. Approximates the residual. // todo xuchenhan@: this prob needs to be scaled by dt
btScalar residualSquare = dn*dn;
if (dn > 0)
{
return 0;
}
btScalar residualSquare = dn*dn;
btVector3 impulse = m_contact->m_c0 * vr;
if (!infoGlobal.m_splitImpulse)
{
@@ -265,8 +271,6 @@ btScalar btDeformableRigidContactConstraint::solveConstraint(const btContactSolv
impulse = impulse_normal + impulse_tangent;
// apply impulse to deformable nodes involved and change their velocities
applyImpulse(impulse);
if (residualSquare < 1e-7)
return residualSquare;
// apply impulse to the rigid/multibodies involved and change their velocities
if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY)
{
@@ -301,12 +305,23 @@ btScalar btDeformableRigidContactConstraint::solveConstraint(const btContactSolv
btScalar btDeformableRigidContactConstraint::solveSplitImpulse(const btContactSolverInfo& infoGlobal)
{
btScalar MAX_PENETRATION_CORRECTION = 0.1;
const btSoftBody::sCti& cti = m_contact->m_cti;
btVector3 vb = getSplitVb();
btScalar p = m_penetration;
btScalar dn = btDot(vb, cti.m_normal) + p * infoGlobal.m_deformable_erp / infoGlobal.m_timeStep;
if (dn > 0)
return 0;
if (m_total_split_impulse + dn > MAX_PENETRATION_CORRECTION)
{
dn = MAX_PENETRATION_CORRECTION - m_total_split_impulse;
}
if (m_total_split_impulse + dn < -MAX_PENETRATION_CORRECTION)
{
dn = -MAX_PENETRATION_CORRECTION - m_total_split_impulse;
}
m_total_split_impulse += dn;
btScalar residualSquare = dn*dn;
const btVector3 impulse = 1.0/m_contact->m_c2 * (cti.m_normal * dn);
applySplitImpulse(impulse);

View File

@@ -148,6 +148,7 @@ public:
btVector3 m_total_normal_dv;
btVector3 m_total_tangent_dv;
btScalar m_penetration;
btScalar m_total_split_impulse;
const btSoftBody::DeformableRigidContact* m_contact;
btDeformableRigidContactConstraint(const btSoftBody::DeformableRigidContact& c, const btContactSolverInfo& infoGlobal);

View File

@@ -147,15 +147,16 @@ void btDeformableContactProjection::setConstraints(const btContactSolverInfo& in
continue;
}
btDeformableFaceRigidContactConstraint constraint(contact, infoGlobal, m_useStrainLimiting);
btVector3 va = constraint.getVa();
btVector3 vb = constraint.getVb();
const btVector3 vr = vb - va;
const btSoftBody::sCti& cti = contact.m_cti;
const btScalar dn = btDot(vr, cti.m_normal);
if (dn < SIMD_EPSILON)
{
m_faceRigidConstraints[i].push_back(constraint);
}
m_faceRigidConstraints[i].push_back(constraint);
// btVector3 va = constraint.getVa();
// btVector3 vb = constraint.getVb();
// const btVector3 vr = vb - va;
// const btSoftBody::sCti& cti = contact.m_cti;
// const btScalar dn = btDot(vr, cti.m_normal);
// if (dn < SIMD_EPSILON)
// {
// m_faceRigidConstraints[i].push_back(constraint);
// }
}
}
}

View File

@@ -41,7 +41,8 @@ btScalar btDeformableMultiBodyConstraintSolver::solveDeformableGroupIterations(b
if (m_leastSquaresResidual <= infoGlobal.m_leastSquaresResidualThreshold || (iteration >= (maxIterations - 1)))
{
#ifdef VERBOSE_RESIDUAL_PRINTF
printf("residual = %f at iteration #%d\n", m_leastSquaresResidual, iteration);
if (iteration >= (maxIterations - 1))
printf("residual = %f at iteration #%d\n", m_leastSquaresResidual, iteration);
#endif
m_analyticsData.m_numSolverCalls++;
m_analyticsData.m_numIterationsUsed = iteration+1;
@@ -133,7 +134,8 @@ void btDeformableMultiBodyConstraintSolver::solveGroupCacheFriendlySplitImpulseI
if (leastSquaresResidual <= infoGlobal.m_leastSquaresResidualThreshold || iteration >= (infoGlobal.m_numIterations - 1))
{
#ifdef VERBOSE_RESIDUAL_PRINTF
printf("residual = %f at iteration #%d\n", leastSquaresResidual, iteration);
if (iteration >= (infoGlobal.m_numIterations - 1))
printf("split impulse residual = %f at iteration #%d\n", leastSquaresResidual, iteration);
#endif
break;
}

View File

@@ -61,7 +61,7 @@ m_deformableBodySolver(deformableBodySolver), m_solverCallback(0)
m_internalTime = 0.0;
m_implicit = false;
m_lineSearch = false;
m_useProjection = true;
m_useProjection = false;
m_ccdIterations = 5;
m_solverDeformableBodyIslandCallback = new DeformableBodyInplaceSolverIslandCallback(constraintSolver, dispatcher);
}
@@ -537,6 +537,7 @@ void btDeformableMultiBodyDynamicsWorld::reinitialize(btScalar timeStep)
}
else
{
m_deformableBodySolver->m_useProjection = false;
m_deformableBodySolver->m_objective->m_preconditioner = m_deformableBodySolver->m_objective->m_KKTPreconditioner;
}