SimulationThread.cpp

00001 /***************************************************************************
00002   tag: Peter Soetens  Tue Dec 21 22:43:07 CET 2004  SimulationThread.cxx 
00003 
00004                         SimulationThread.cxx -  description
00005                            -------------------
00006     begin                : Tue December 21 2004
00007     copyright            : (C) 2004 Peter Soetens
00008     email                : peter.soetens@mech.kuleuven.ac.be
00009  
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU General Public                   *
00013  *   License as published by the Free Software Foundation;                 *
00014  *   version 2 of the License.                                             *
00015  *                                                                         *
00016  *   As a special exception, you may use this file as part of a free       *
00017  *   software library without restriction.  Specifically, if other files   *
00018  *   instantiate templates or use macros or inline functions from this     *
00019  *   file, or you compile this file and link it with other files to        *
00020  *   produce an executable, this file does not by itself cause the         *
00021  *   resulting executable to be covered by the GNU General Public          *
00022  *   License.  This exception does not however invalidate any other        *
00023  *   reasons why the executable file might be covered by the GNU General   *
00024  *   Public License.                                                       *
00025  *                                                                         *
00026  *   This library is distributed in the hope that it will be useful,       *
00027  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00028  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00029  *   Lesser General Public License for more details.                       *
00030  *                                                                         *
00031  *   You should have received a copy of the GNU General Public             *
00032  *   License along with this library; if not, write to the Free Software   *
00033  *   Foundation, Inc., 59 Temple Place,                                    *
00034  *   Suite 330, Boston, MA  02111-1307  USA                                *
00035  *                                                                         *
00036  ***************************************************************************/
00037  
00038  
00039 
00040 #include "SimulationThread.hpp"
00041 #include "TimeService.hpp"
00042 #include "SimulationActivity.hpp"
00043 #include "Logger.hpp"
00044 #include <os/threads.hpp>
00045 
00046 #include <os/StartStopManager.hpp>
00047 namespace RTT
00048 {
00049     namespace
00050     {
00051         // Stop it before the application quits.
00052         void stopSIMThread()
00053         {
00054             SimulationThread::Release();
00055         }
00056 
00057         OS::CleanupFunction SIMCleanup( &stopSIMThread );
00058     }
00059 }
00060 
00061 namespace RTT
00062 {
00063     
00064     // The static class variables
00065     SimulationThreadPtr SimulationThread::_instance;
00066 
00067     SimulationThreadPtr SimulationThread::Instance(double period)
00068     {
00069         if ( !_instance )
00070         {
00071             _instance.reset( new SimulationThread(period) );
00072         }
00073 
00074         return _instance;
00075     }
00076 
00077     bool SimulationThread::Release()
00078     {
00079         _instance.reset();
00080         return true;
00081     }
00082 
00083 
00084     SimulationThread::SimulationThread(double period)
00085         : TimerThread( OS::LowestPriority,
00086                       "SimulationThread", 
00087                       period),
00088           beat( TimeService::Instance() ), maxsteps_(0), sim_running(false)
00089     {
00090         this->setScheduler(ORO_SCHED_OTHER);
00091         this->continuousStepping( true );
00092         Logger::log() << Logger::Info << this->getName() <<" created with "<< this->getPeriod() <<"s periodicity";
00093         Logger::log() << Logger::Info << " and priority " << this->getPriority() << Logger::endl;
00094     }
00095 
00096     SimulationThread::~SimulationThread()
00097     {
00098     }
00099 
00100     bool SimulationThread::isRunning() const
00101     {
00102         return sim_running || PeriodicThread::isRunning();
00103     }
00104 
00105     bool SimulationThread::start()
00106     {
00107         maxsteps_ = 0;
00108         return OS::PeriodicThread::start();
00109     }
00110     
00111     bool SimulationThread::start(unsigned int maxsteps)
00112     {
00113         if (maxsteps == 0)
00114             return false;
00115         maxsteps_ = maxsteps;
00116         return OS::PeriodicThread::start();
00117     }
00118 
00119     bool SimulationThread::run(unsigned int ms)
00120     {
00121         if ( ms == 0 || this->isRunning() || this->initialize() == false )
00122             return false;
00123         unsigned int cur = 0;
00124         this->sim_running = true;
00125         while( cur != ms ) {
00126             ++cur;
00127             TimerThread::step();
00128             beat->secondsChange(this->getPeriod());
00129         }
00130         this->sim_running = false;
00131         this->finalize();
00132         return true;
00133     }
00134 
00135     bool SimulationThread::initialize()
00136     {
00137         Logger::log() << Logger::Info << "SimulationThread takes over system time."<<Logger::nl;
00138         Logger::log() << Logger::Info << "System time will increase significantly faster."<<Logger::endl;
00139         
00140         // we will update the clock in step()
00141         beat->enableSystemClock( false );
00142 
00143         cursteps = 0;
00144         // No TimerThread::initialize() to allow 'freeze'
00145         return true;
00146     }
00147 
00148     void SimulationThread::finalize()
00149     {
00150         Logger::log() << Logger::Info << "SimulationThread releases system time."<<Logger::endl;
00151         // release systemclock again.
00152         beat->enableSystemClock( true );
00153 
00154         // DO NOT CALL TimerThread::finalize(), since we want to be able to start/stop the
00155         // SimulationThread and inspect the activities still running.
00156     }
00157 
00158     void SimulationThread::step()
00159     {
00160         ++cursteps;
00161 
00162         if ( maxsteps_ == 0 || cursteps < maxsteps_ + 1 ) {
00163             TimerThread::step();
00164             beat->secondsChange(this->getPeriod());
00165         }
00166 
00167         // call stop once :
00168         if ( cursteps == maxsteps_ ) { // if maxsteps == 0, will never call stop().
00169             this->setToStop();
00170         }
00171     }
00172 
00173 }

Generated on Tue Mar 25 17:41:52 2008 for OrocosReal-TimeToolkit by  doxygen 1.5.3