00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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
00088
00089
00090
00091
00092
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 ( dynamic_cast<simulation::AnimateBeginEvent*>(event))
00119 {
00120
00121 if (outfile && mmodel)
00122 {
00123 if (!kineticEnergyThresholdReached)
00124 {
00125 double time = getContext()->getTime();
00126
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 {
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 {
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 {
00146 savedKineticEnergy = gnode->mass->getKineticEnergy();
00147
00148 timeToTestEnergyIncrease+=f_keperiod.getValue();
00149 }
00150 }
00151 }
00152 }
00153
00154 if (nextTime<f_time.getValue().size())
00155 {
00156
00157 lastTime = f_time.getValue()[nextTime];
00158 if (time >= lastTime)
00159 {
00160
00161 (*outfile) << "T= "<< time << "\n";
00162 if (f_writeX.getValue())
00163 {
00164 (*outfile) << " X= ";
00165 mmodel->writeX(*outfile);
00166 (*outfile) << "\n";
00167 }
00168
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
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 }
00207
00208 }
00209
00210 }
00211
00212 #endif