示例#1
0
// TODO: Implement in a cleaner way -- create a function in fsys that checks if kinematic constraints are respected
bool ImpactFrictionMap::noImpulsesToKinematicGeometry( const FlowableSystem& fsys, const SparseMatrixsc& N, const VectorXs& alpha, const SparseMatrixsc& D, const VectorXs& beta, const VectorXs& v0 )
{
  const VectorXs dv{ fsys.Minv() * ( N * alpha + D * beta ) };
  assert( unsigned( v0.size() ) % fsys.numVelDoFsPerBody() == 0 );
  const unsigned nbodies = unsigned( v0.size() ) / fsys.numVelDoFsPerBody();
  for( unsigned i = 0; i < nbodies; ++i )
  {
    if( fsys.isKinematicallyScripted( i ) )
    {
      if( fsys.numVelDoFsPerBody() == 6 )
      {
        // 6-DoF rigid body in 3D
        if( ( dv.segment<3>( 3 * i ).array() != 0.0 ).any() )
        {
          return false;
        }
        if( ( dv.segment<3>( 3 * nbodies + 3 * i ).array() != 0.0 ).any() )
        {
          return false;
        }
      }
      else if( fsys.numVelDoFsPerBody() == 2 )
      {
        // 2-DoF ball in 2D
        if( ( dv.segment<2>( 2 * i ).array() != 0.0 ).any() )
        {
          return false;
        }
      }
      else
      {
        std::cerr << "Unhandled code path in ImpactFrictionMap::noImpulsesToKinematicGeometry. This is a bug." << std::endl;
        std::exit( EXIT_FAILURE );
      }
    }
  }
  return true;
}
void SymplecticEulerMap::flow( const VectorXs& q0, const VectorXs& v0, FlowableSystem& fsys, const unsigned iteration, const scalar& dt, VectorXs& q1, VectorXs& v1 )
{
  assert( iteration > 0 );
  const scalar start_time{ ( iteration - 1 ) * dt };

  // Use q1 as temporary storage for the force
  fsys.computeForce( q0, v0, start_time, q1 );

  // Zero the force for fixed bodies
  const unsigned nbodies{ fsys.numBodies() };
  for( unsigned bdy_idx = 0; bdy_idx < nbodies; ++bdy_idx )
  {
    if( fsys.isKinematicallyScripted( bdy_idx ) )
    {
      q1.segment<3>( 3 * bdy_idx ).setZero();
    }
  }

  // Velocity update
  v1 = v0 + dt * fsys.Minv() * q1;

  // Position update
  q1 = q0 + dt * v1;
}