Ejemplo n.º 1
0
void RestShapeSpringsForceField<Rigid3Types>::addForce(const core::MechanicalParams* /* mparams */, DataVecDeriv& f, const DataVecCoord& x, const DataVecDeriv& /* v */)
{
    sofa::helper::WriteAccessor< DataVecDeriv > f1 = f;
    sofa::helper::ReadAccessor< DataVecCoord > p1 = x;

    sofa::helper::ReadAccessor< DataVecCoord > p0 = *getExtPosition();

    f1.resize(p1.size());

    if (recompute_indices.getValue())
    {
        recomputeIndices();
    }

    const VecReal& k = stiffness.getValue();
    const VecReal& k_a = angularStiffness.getValue();

    for (unsigned int i = 0; i < m_indices.size(); i++)
    {
        const unsigned int index = m_indices[i];
        unsigned int ext_index = m_indices[i];
        if(useRestMState)
            ext_index= m_ext_indices[i];

        // translation
        if (i >= m_pivots.size())
        {
            Vec3d dx = p1[index].getCenter() - p0[ext_index].getCenter();
            getVCenter(f1[index]) -=  dx * (i < k.size() ? k[i] : k[0]) ;
        }
        else
        {
            CPos localPivot = p0[ext_index].getOrientation().inverseRotate(m_pivots[i] - p0[ext_index].getCenter());
            CPos rotatedPivot = p1[index].getOrientation().rotate(localPivot);
            CPos pivot2 = p1[index].getCenter() + rotatedPivot;
            CPos dx = pivot2 - m_pivots[i];
            getVCenter(f1[index]) -= dx * (i < k.size() ? k[i] : k[0]) ;
        }

        // rotation
        Quatd dq = p1[index].getOrientation() * p0[ext_index].getOrientation().inverse();
        Vec3d dir;
        double angle=0;
        dq.normalize();

        if (dq[3] < 0)
        {
            dq = dq * -1.0;
        }

        if (dq[3] < 0.999999999999999)
            dq.quatToAxis(dir, angle);

        getVOrientation(f1[index]) -= dir * angle * (i < k_a.size() ? k_a[i] : k_a[0]);
    }
}
Ejemplo n.º 2
0
TEST(Boxes, ConstraintViolation)
{
  const double TOL = 1e-6;
  const double DT = 1e-2;
  const std::string FNAME("box.xml");
  const std::string BOX_ID("box");
  shared_ptr<TimeSteppingSimulator> sim;
  shared_ptr<RigidBody> box;
  const unsigned NTIMES = 100;

  // log contact 
  Moby::Log<Moby::OutputToFile>::reporting_level = (LOG_SIMULATOR | LOG_CONSTRAINT);
  Moby::OutputToFile::stream.open("logging.out");

  // log energy
  std::ofstream energy_out("energy.dat");

  // do this multiple times
  for (unsigned j=0; j< NTIMES; j++)
  {
    // load in the box file
    map<std::string, BasePtr> READ_MAP = XMLReader::read(FNAME);
  
    // look for the simulator
    find(READ_MAP, sim);

    // look for the box 
    find(READ_MAP, box, BOX_ID);

    // set tolerance for constraint stabilization and minimum step size
//    sim->min_step_size = TOL/10000.0;
//    sim->min_step_size = 1e-5;
    sim->min_step_size = 1e-1;
    sim->cstab.eps = -NEAR_ZERO;

    // modify the initial orientation of the box
    Quatd q;
    q.x = (double) rand() / RAND_MAX * 2.0 - 1.0;
    q.y = (double) rand() / RAND_MAX * 2.0 - 1.0;
    q.z = (double) rand() / RAND_MAX * 2.0 - 1.0;
    q.w = (double) rand() / RAND_MAX * 2.0 - 1.0;
    q.normalize();
    Pose3d P = *box->get_pose();
    P.q = q;
    box->set_pose(P);

    // modify the velocity of the box
    Vector3d xd(box->get_inertial_pose());
    Vector3d w(box->get_inertial_pose());
    SVelocityd v(box->get_inertial_pose());
    for (unsigned i=0; i< 3; i++)
    {
      xd[i] = (double) rand() / RAND_MAX * 2.0 - 1.0;
      w[i] = (double) rand() / RAND_MAX * 2.0 - 1.0;
    }
    v.set_linear(xd);
    v.set_angular(w);
    box->set_velocity(v);
    
    // set the first no K.E. time 
    double no_KE_time = 0.0;

    // setup the maximum violation
    double max_vio = 0.0;

    // reset steps
    unsigned step = 0;

    // integrate the box until it has no kinetic energy for 1/2 sec 
    while (true)
    {
      // execute the step
      sim->step(DT);
 
      // get the constraint violation
      const vector<PairwiseDistInfo>& pdi = sim->get_pairwise_distances();
      for (unsigned i=0; i< pdi.size(); i++)
        max_vio = std::min(max_vio, pdi[i].dist);

      // get the kinetic energy of the box
      double KE = box->calc_kinetic_energy();
      energy_out << KE << std::endl;

      // see whether there is no kinetic energy
      if (KE < 1e-6)
      {
        if (sim->current_time - no_KE_time > 0.5)
          break;
      }
      else
        no_KE_time = sim->current_time;
      if (step++ % 1000 == 0)
        std::cerr << "." << std::flush;
    }

    // only want to print out one message about violation
    EXPECT_GT(max_vio, -TOL);
    std::cerr << "+" << std::flush;
    energy_out.close();
  }
}
Ejemplo n.º 3
0
void UniformMass<RigidTypes, MassType>::loadFromFileRigidImpl(const string& filename)
{
    TemporaryLocale locale(LC_ALL, "C") ;

    if (!filename.empty())
    {
        MassType m = getMass();
        string unconstingFilenameQuirck = filename ;
        if (!DataRepository.findFile(unconstingFilenameQuirck))
            msg_error(this) << "cannot find file '" << filename << "'.\n"  ;
        else
        {
            char	cmd[64];
            FILE*	file;
            if ((file = fopen(filename.c_str(), "r")) == NULL)
            {
                msg_error(this) << "cannot open file '" << filename << "'.\n" ;
            }
            else
            {
                {
                    skipToEOL(file);
                    ostringstream cmdScanFormat;
                    cmdScanFormat << "%" << (sizeof(cmd) - 1) << "s";
                    while (fscanf(file, cmdScanFormat.str().c_str(), cmd) != EOF)
                    {
                        if (!strcmp(cmd,"inrt"))
                        {
                            for (int i = 0; i < 3; i++){
                                for (int j = 0; j < 3; j++){
                                    double tmp = 0;
                                    if( fscanf(file, "%lf", &(tmp)) < 1 ){
                                        msg_error(this) << "error while reading file '" << filename << "'.\n";
                                    }
                                    m.inertiaMatrix[i][j]=tmp;
                                }
                            }
                        }
                        else if (!strcmp(cmd,"cntr") || !strcmp(cmd,"center") )
                        {
                            Vec3d center;
                            for (int i = 0; i < 3; ++i)
                            {
                                if( fscanf(file, "%lf", &(center[i])) < 1 ){
                                    msg_error(this) << "error reading file '" << filename << "'.";
                                }
                            }
                        }
                        else if (!strcmp(cmd,"mass"))
                        {
                            double mass;
                            if( fscanf(file, "%lf", &mass) > 0 )
                            {
                                if (!this->d_mass.isSet())
                                    m.mass = mass;
                            }
                            else
                                msg_error(this) << "error reading file '" << filename <<  "'." << msgendl
                                                << "Unable to decode command 'mass'";
                        }
                        else if (!strcmp(cmd,"volm"))
                        {
                            double tmp;
                            if( fscanf(file, "%lf", &(tmp)) < 1 )
                                msg_error(this) << "error reading file '" << filename << "'." << msgendl
                                                << "Unable to decode command 'volm'." << msgendl;
                            m.volume = tmp ;
                        }
                        else if (!strcmp(cmd,"frme"))
                        {
                            Quatd orient;
                            for (int i = 0; i < 4; ++i)
                            {
                                if( fscanf(file, "%lf", &(orient[i])) < 1 )
                                    msg_error(this) << "error reading file '" << filename << "'." << msgendl
                                                    << "Unable to decode command 'frme' at index " << i ;
                            }
                            orient.normalize();
                        }
                        else if (!strcmp(cmd,"grav"))
                        {
                            Vec3d gravity;
                            if( fscanf(file, "%lf %lf %lf\n", &(gravity.x()), &(gravity.y()), &(gravity.z())) < 3 )
                                msg_warning(this) << "error reading file '" << filename << "'." << msgendl
                                                  << " Unable to decode command 'gravity'.";
                        }
                        else if (!strcmp(cmd,"visc"))
                        {
                            double viscosity = 0;
                            if( fscanf(file, "%lf", &viscosity) < 1 )
                                msg_warning(this) << "error reading file '" << filename << "'.\n"
                                                     " Unable to decode command 'visc'. \n";
                        }
                        else if (!strcmp(cmd,"stck"))
                        {
                            double tmp;
                            if( fscanf(file, "%lf", &tmp) < 1 ) //&(MSparams.default_stick));
                                msg_warning(this) << "error reading file '" << filename << "'.\n"
                                                  << "Unable to decode command 'stck'. \n";

                        }
                        else if (!strcmp(cmd,"step"))
                        {
                            double tmp;
                            if( fscanf(file, "%lf", &tmp) < 1 ) //&(MSparams.default_dt));
                                msg_warning(this) << "error reading file '" << filename << "'.\n"
                                                  << "Unable to decode command 'step'. \n";
                        }
                        else if (!strcmp(cmd,"prec"))
                        {
                            double tmp;
                            if( fscanf(file, "%lf", &tmp) < 1 ) //&(MSparams.default_prec));
                            {
                                msg_warning(this) << "error reading file '" << filename << "'.\n"
                                                  << "Unable to decode command 'prec'. \n" ;
                            }
                        }
                        else if (cmd[0] == '#')	// it's a comment
                        {
                            skipToEOL(file);
                        }
                        else		// it's an unknown keyword
                        {
                            msg_warning(this) << "error reading file '" << filename << "'. \n"
                                              << "Unable to decode an unknow command '"<< cmd << "'. \n" ;
                            skipToEOL(file);
                        }
                    }
                }
                fclose(file);
            }
        }
        setMass(m);
    }
    else if (d_totalMass.getValue()>0 && mstate!=NULL) d_mass.setValue((Real)d_totalMass.getValue() / mstate->getSize());
}