WriteState.inl

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 #ifndef SOFA_COMPONENT_MISC_WRITESTATE_INL
00026 #define SOFA_COMPONENT_MISC_WRITESTATE_INL
00027 
00028 #include <sofa/component/misc/WriteState.h>
00029 #include <sofa/simulation/tree/GNode.h>
00030 
00031 #include <fstream>
00032 
00033 namespace sofa
00034 {
00035 
00036   namespace component
00037   {
00038 
00039     namespace misc
00040     {
00041 
00042 
00043       WriteState::WriteState()
00044   : f_filename( initData(&f_filename, "filename", "output file name"))
00045   , f_writeX( initData(&f_writeX, true, "writeX", "flag enabling output of X vector"))
00046   , f_writeV( initData(&f_writeV, false, "writeV", "flag enabling output of V vector"))
00047   , f_interval( initData(&f_interval, 0.0, "interval", "time duration between outputs"))
00048   , f_time( initData(&f_time, helper::vector<double>(0), "time", "set time to write outputs"))
00049   , f_period( initData(&f_period, 0.0, "period", "period between outputs"))
00050   , f_DOFsX( initData(&f_DOFsX, helper::vector<unsigned int>(0), "DOFsX", "set the position DOFs to write"))
00051   , f_DOFsV( initData(&f_DOFsV, helper::vector<unsigned int>(0), "DOFsV", "set the velocity DOFs to write"))
00052   , f_stopAt( initData(&f_stopAt, 0.0, "stopAt", "stop the simulation when the given threshold is reached"))
00053   , f_keperiod( initData(&f_keperiod, 0.0, "keperiod", "set the period to measure the kinetic energy increase"))
00054   , mmodel(NULL)
00055   , outfile(NULL)
00056   , nextTime(0)
00057   , lastTime(0)
00058   , kineticEnergyThresholdReached(false)
00059   , timeToTestEnergyIncrease(0)
00060   , savedKineticEnergy(0)
00061       {
00062     this->f_listening.setValue(true);
00063       }
00064 
00065 
00066       WriteState::~WriteState()
00067       {
00068     if (outfile)
00069       delete outfile;
00070       }
00071 
00072 
00073       void WriteState::init()
00074       {
00075     mmodel = dynamic_cast<core::componentmodel::behavior::BaseMechanicalState*>(this->getContext()->getMechanicalState());
00076 
00077     // test the size and range of the DOFs to write in the file output
00078     if (mmodel)
00079       {
00080         timeToTestEnergyIncrease = f_keperiod.getValue();       
00081       }
00083     
00084     const std::string& filename = f_filename.getValue();
00085     if (!filename.empty())
00086       {
00087 //      std::ifstream infile(filename.c_str());
00088 //      if( infile.is_open() )
00089 //        {
00090 //      std::cerr << "ERROR: file "<<filename<<" already exists. Remove it to record new motion."<<std::endl;
00091 //        }
00092 //      else                
00093           {
00094         outfile = new std::ofstream(filename.c_str());
00095         if( !outfile->is_open() )
00096           {
00097             std::cerr << "Error creating file "<<filename<<std::endl;
00098             delete outfile;
00099             outfile = NULL;
00100           }
00101           }
00102       }
00103       }
00104 
00105 
00106       void WriteState::reset()
00107       {
00108     nextTime = 0;
00109     lastTime = 0;
00110     kineticEnergyThresholdReached = false;
00111     timeToTestEnergyIncrease = f_keperiod.getValue();  
00112     savedKineticEnergy = 0;
00113       }
00114 
00115 
00116       void WriteState::handleEvent(sofa::core::objectmodel::Event* event)
00117       {
00118     if (/* simulation::AnimateBeginEvent* ev = */ dynamic_cast<simulation::AnimateBeginEvent*>(event))
00119       {
00120       
00121         if (outfile && mmodel)
00122           {
00123         if (!kineticEnergyThresholdReached)
00124           {  
00125             double time = getContext()->getTime();
00126             // the time to measure the increase of energy is reached
00127             if (f_stopAt.getValue())
00128               {
00129             if (time > timeToTestEnergyIncrease)
00130               {
00131                 simulation::tree::GNode *gnode = dynamic_cast<simulation::tree::GNode *>(this->getContext());
00132                 if (!gnode->mass)
00133                   { // Error: the mechanical model has no mass
00134                 std::cerr << "Error: Kinetic energy can not be computed. The mass for " << mmodel->getName() << " has no been defined" << std::endl;
00135                 exit(-1);
00136                   }
00137                 else
00138                   {// computes the energy increase
00139                 if (fabs(gnode->mass->getKineticEnergy() - savedKineticEnergy) < f_stopAt.getValue())
00140                   {
00141                     std::cout << "WriteState has been stopped. Kinetic energy threshold has been reached" << std::endl;
00142                     kineticEnergyThresholdReached = true;                       
00143                   }
00144                 else
00145                   { // save the last energy measured
00146                     savedKineticEnergy = gnode->mass->getKineticEnergy();
00147                     // increase the period to measure the energy
00148                     timeToTestEnergyIncrease+=f_keperiod.getValue();
00149                   }
00150                   }
00151               }
00152               }
00153         
00154             if (nextTime<f_time.getValue().size())
00155               {
00156             // store the actual time instant 
00157             lastTime = f_time.getValue()[nextTime];
00158             if (time >= lastTime) // if the time simulation is >= that the actual time instant
00159               {
00160                 // write the X state
00161                 (*outfile) << "T= "<< time << "\n";
00162                 if (f_writeX.getValue())
00163                   {
00164                 (*outfile) << "  X= ";
00165                 mmodel->writeX(*outfile);
00166                 (*outfile) << "\n";
00167                   }
00168                 //write the V state
00169                   if (f_writeV.getValue())
00170                 {
00171                   (*outfile) << "  V= ";
00172                   mmodel->writeV(*outfile);
00173                   (*outfile) << "\n";
00174                 }
00175                 outfile->flush();
00176                 nextTime++;
00177               }
00178               }
00179             else
00180               {
00181             // write the state using a period
00182             if (time >= (lastTime + f_period.getValue()))
00183               {
00184                 (*outfile) << "T= "<< time << "\n";
00185                 if (f_writeX.getValue())
00186                   {
00187                 (*outfile) << "  X= ";                          
00188                 mmodel->writeX(*outfile);
00189                 (*outfile) << "\n";
00190                   }
00191                 if (f_writeV.getValue())
00192                   {
00193                 (*outfile) << "  V= ";
00194                 mmodel->writeV(*outfile);
00195                 (*outfile) << "\n";
00196                   }
00197                 outfile->flush();
00198                 lastTime += f_period.getValue();
00199               }
00200               }
00201           }
00202           }
00203       }
00204       }
00205 
00206     } // namespace misc
00207 
00208   } // namespace component
00209 
00210 } // namespace sofa
00211 
00212 #endif

Generated on Sun Nov 23 03:42:46 2008 for Sofa by  doxygen 1.5.7.1