switch to Baraff style constraint

This commit is contained in:
Xuchen Han
2019-08-09 13:39:25 -07:00
parent 27492887bf
commit 5b8df6a708
5 changed files with 98 additions and 47 deletions

View File

@@ -228,11 +228,11 @@ void DeformableRigid::initPhysics()
psb->getCollisionShape()->setMargin(0.1); psb->getCollisionShape()->setMargin(0.1);
psb->generateBendingConstraints(2); psb->generateBendingConstraints(2);
psb->setTotalMass(1); psb->setTotalMass(1);
psb->setSpringStiffness(1); psb->setSpringStiffness(2);
psb->setDampingCoefficient(0.01); psb->setDampingCoefficient(0.05);
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb->m_cfg.kCHR = 1; // collision hardness with rigid body psb->m_cfg.kCHR = 1; // collision hardness with rigid body
psb->m_cfg.kDF = 1; psb->m_cfg.kDF = 0;
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD; psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
getDeformableDynamicsWorld()->addSoftBody(psb); getDeformableDynamicsWorld()->addSoftBody(psb);
getDeformableDynamicsWorld()->addForce(psb, new btDeformableMassSpringForce()); getDeformableDynamicsWorld()->addForce(psb, new btDeformableMassSpringForce());

View File

@@ -331,14 +331,15 @@ void GraspDeformable::initPhysics()
psb->getCollisionShape()->setMargin(0.1); psb->getCollisionShape()->setMargin(0.1);
psb->setTotalMass(1); psb->setTotalMass(1);
psb->setSpringStiffness(0); psb->setSpringStiffness(0);
psb->setDampingCoefficient(0.04); psb->setDampingCoefficient(0.02);
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb->m_cfg.kCHR = 1; // collision hardness with rigid body psb->m_cfg.kCHR = 1; // collision hardness with rigid body
psb->m_cfg.kDF = 2; psb->m_cfg.kDF = 0;
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
getDeformableDynamicsWorld()->addSoftBody(psb); getDeformableDynamicsWorld()->addSoftBody(psb);
getDeformableDynamicsWorld()->addForce(psb, new btDeformableMassSpringForce()); getDeformableDynamicsWorld()->addForce(psb, new btDeformableMassSpringForce());
getDeformableDynamicsWorld()->addForce(psb, new btDeformableGravityForce(gravity)); getDeformableDynamicsWorld()->addForce(psb, new btDeformableGravityForce(gravity));
getDeformableDynamicsWorld()->addForce(psb, new btDeformableCorotatedForce(2,2)); getDeformableDynamicsWorld()->addForce(psb, new btDeformableCorotatedForce(1,1));
} }
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);

View File

@@ -32,62 +32,108 @@ public:
virtual ~btConjugateGradient(){} virtual ~btConjugateGradient(){}
// // return the number of iterations taken
// int solve(MatrixX& A, TVStack& x, const TVStack& b, btScalar tolerance)
// {
// BT_PROFILE("CGSolve");
// btAssert(x.size() == b.size());
// reinitialize(b);
//
// // r = b - A * x --with assigned dof zeroed out
// A.multiply(x, temp);
// r = sub(b, temp);
// A.project(r);
//
// btScalar r_norm = std::sqrt(squaredNorm(r));
// if (r_norm < tolerance) {
// std::cout << "Iteration = 0" << std::endl;
// std::cout << "Two norm of the residual = " << r_norm << std::endl;
// return 0;
// }
//
// // z = M^(-1) * r
// A.precondition(r, z);
// p = z;
// // temp = A*p
// A.multiply(p, temp);
// A.project(temp);
// btScalar r_dot_z = dot(z,r), r_dot_z_new;
// // alpha = r^T * z / (p^T * A * p)
// btScalar alpha = r_dot_z / dot(p, temp), beta;
//
// for (int k = 1; k < max_iterations; k++) {
// // x += alpha * p;
// // r -= alpha * temp;
// multAndAddTo(alpha, p, x);
// multAndAddTo(-alpha, temp, r);
// // zero out the dofs of r
// A.project(r);
//// A.enforceConstraint(x);
// r_norm = std::sqrt(squaredNorm(r));
//
// if (r_norm < tolerance) {
// std::cout << "ConjugateGradient iterations " << k << std::endl;
// return k;
// }
//
// // z = M^(-1) * r
// A.precondition(r, z);
// r_dot_z_new = dot(r,z);
// beta = r_dot_z_new/ r_dot_z;
// r_dot_z = r_dot_z_new;
// // p = z + beta * p;
// p = multAndAdd(beta, p, z);
// // temp = A * p;
// A.multiply(p, temp);
// A.project(temp);
// // alpha = r^T * z / (p^T * A * p)
// alpha = r_dot_z / dot(p, temp);
// }
// std::cout << "ConjugateGradient max iterations reached " << max_iterations << std::endl;
// return max_iterations;
// }
// return the number of iterations taken // return the number of iterations taken
int solve(MatrixX& A, TVStack& x, const TVStack& b, btScalar tolerance) int solve(MatrixX& A, TVStack& x, const TVStack& b, btScalar tolerance)
{ {
BT_PROFILE("CGSolve"); BT_PROFILE("CGSolve");
btAssert(x.size() == b.size()); btAssert(x.size() == b.size());
reinitialize(b); reinitialize(b);
// r = b - A * x --with assigned dof zeroed out // r = b - A * x --with assigned dof zeroed out
A.multiply(x, temp); A.multiply(x, temp);
r = sub(b, temp); r = sub(b, temp);
A.project(r); A.project(r);
A.enforceConstraint(x);
btScalar r_norm = std::sqrt(squaredNorm(r));
if (r_norm < tolerance) {
std::cout << "Iteration = 0" << std::endl;
std::cout << "Two norm of the residual = " << r_norm << std::endl;
return 0;
}
// z = M^(-1) * r // z = M^(-1) * r
A.precondition(r, z); A.precondition(r, z);
A.project(z);
btScalar r_dot_z = dot(z,r);
if (r_dot_z < tolerance) {
std::cout << "Iteration = 0" << std::endl;
std::cout << "Two norm of the residual = " << r_dot_z << std::endl;
return 0;
}
p = z; p = z;
// temp = A*p btScalar r_dot_z_new = r_dot_z;
A.multiply(p, temp);
btScalar r_dot_z = dot(z,r), r_dot_z_new;
// alpha = r^T * z / (p^T * A * p)
btScalar alpha = r_dot_z / dot(p, temp), beta;
for (int k = 1; k < max_iterations; k++) { for (int k = 1; k < max_iterations; k++) {
// temp = A*p
A.multiply(p, temp);
A.project(temp);
// alpha = r^T * z / (p^T * A * p)
btScalar alpha = r_dot_z_new / dot(p, temp);
// x += alpha * p; // x += alpha * p;
// r -= alpha * temp;
multAndAddTo(alpha, p, x); multAndAddTo(alpha, p, x);
// r -= alpha * temp;
multAndAddTo(-alpha, temp, r); multAndAddTo(-alpha, temp, r);
// zero out the dofs of r // z = M^(-1) * r
A.project(r); A.precondition(r, z);
A.enforceConstraint(x); r_dot_z = r_dot_z_new;
r_norm = std::sqrt(squaredNorm(r)); r_dot_z_new = dot(r,z);
if (r_dot_z_new < tolerance) {
if (r_norm < tolerance) {
std::cout << "ConjugateGradient iterations " << k << std::endl; std::cout << "ConjugateGradient iterations " << k << std::endl;
return k; return k;
} }
btScalar beta = r_dot_z_new/ r_dot_z;
// z = M^(-1) * r
A.precondition(r, z);
r_dot_z_new = dot(r,z);
beta = r_dot_z_new/ r_dot_z;
r_dot_z = r_dot_z_new;
// p = z + beta * p;
p = multAndAdd(beta, p, z); p = multAndAdd(beta, p, z);
// temp = A * p;
A.multiply(p, temp);
// alpha = r^T * z / (p^T * A * p)
alpha = r_dot_z / dot(p, temp);
} }
std::cout << "ConjugateGradient max iterations reached " << max_iterations << std::endl; std::cout << "ConjugateGradient max iterations reached " << max_iterations << std::endl;
return max_iterations; return max_iterations;

View File

@@ -73,7 +73,6 @@ public:
{ {
BT_PROFILE("enforceConstraint"); BT_PROFILE("enforceConstraint");
projection.enforceConstraint(x); projection.enforceConstraint(x);
updateVelocity(x);
} }
// add dv to velocity // add dv to velocity
@@ -86,7 +85,6 @@ public:
void project(TVStack& r) void project(TVStack& r)
{ {
BT_PROFILE("project"); BT_PROFILE("project");
projection.update();
projection.project(r); projection.project(r);
} }

View File

@@ -31,20 +31,20 @@ btDeformableBodySolver::~btDeformableBodySolver()
void btDeformableBodySolver::solveConstraints(float solverdt) void btDeformableBodySolver::solveConstraints(float solverdt)
{ {
BT_PROFILE("solveConstraints"); BT_PROFILE("solveConstraints");
// add constraints to the solver
setConstraints();
// save v_{n+1}^* velocity after explicit forces // save v_{n+1}^* velocity after explicit forces
backupVelocity(); backupVelocity();
m_objective->computeResidual(solverdt, m_residual); // add constraints to the solver
setConstraints();
m_objective->computeResidual(solverdt, m_residual);
computeStep(m_dv, m_residual); computeStep(m_dv, m_residual);
updateVelocity(); updateVelocity();
} }
void btDeformableBodySolver::computeStep(TVStack& dv, const TVStack& residual) void btDeformableBodySolver::computeStep(TVStack& dv, const TVStack& residual)
{ {
btScalar tolerance = std::numeric_limits<float>::epsilon()* 1024 * m_objective->computeNorm(residual); btScalar tolerance = std::numeric_limits<float>::epsilon()* 1024 * m_objective->computeNorm(residual);
m_cg.solve(*m_objective, dv, residual, tolerance); m_cg.solve(*m_objective, dv, residual, tolerance);
} }
@@ -75,6 +75,12 @@ void btDeformableBodySolver::setConstraints()
{ {
BT_PROFILE("setConstraint"); BT_PROFILE("setConstraint");
m_objective->setConstraints(); m_objective->setConstraints();
for (int i = 0; i < 10; ++i)
{
m_objective->projection.update();
m_objective->enforceConstraint(m_dv);
m_objective->updateVelocity(m_dv);
}
} }
void btDeformableBodySolver::setWorld(btDeformableRigidDynamicsWorld* world) void btDeformableBodySolver::setWorld(btDeformableRigidDynamicsWorld* world)