AnimatLab  2
Test
SimulationThread.cpp
1 #include "StdAfx.h"
2 #include "IMovableItemCallback.h"
3 #include "ISimGUICallback.h"
4 #include "IMotorizedJoint.h"
5 #include "AnimatBase.h"
6 
7 #include "Node.h"
8 #include "Link.h"
9 #include "IPhysicsMovableItem.h"
10 #include "IPhysicsBody.h"
11 #include "BoundingBox.h"
12 #include "MovableItem.h"
13 #include "BodyPart.h"
14 #include "Joint.h"
15 #include "ReceptiveField.h"
16 #include "ContactSensor.h"
17 #include "RigidBody.h"
18 #include "Structure.h"
19 #include "NeuralModule.h"
20 #include "Adapter.h"
21 #include "NervousSystem.h"
22 #include "Organism.h"
23 #include "ActivatedItem.h"
24 #include "ActivatedItemMgr.h"
25 #include "DataChartMgr.h"
26 #include "ExternalStimuliMgr.h"
27 #include "KeyFrame.h"
28 #include "SimulationRecorder.h"
29 #include "OdorType.h"
30 #include "Odor.h"
31 #include "Light.h"
32 #include "LightManager.h"
33 #include "Simulator.h"
34 #include "SimulationThread.h"
35 #include "SimulationMgr.h"
36 
37 #include "RobotInterface.h"
38 #include "RobotIOControl.h"
39 #include "RobotPartInterface.h"
40 
41 namespace AnimatSim
42 {
43 
44 SimulationThread::SimulationThread(void)
45 {
46  m_lpSim = NULL;
47  m_bThreadProcessing = false;
48  m_bNeedToStop = false;
49 }
50 
51 SimulationThread::~SimulationThread(void)
52 {
53 try
54 {
55  ShutdownSimulation();
56 
57  if(m_lpSim)
58  {
59  delete m_lpSim;
60  m_lpSim = NULL;
61  }
62 
63 }
64 catch(...)
65 {Std_TraceMsg(0, "Caught Error in desctructor of SimulationThread\r\n", "", -1, false, true);}
66 }
67 
68 bool SimulationThread::NeedToStopSim() {return m_bNeedToStop;}
69 
70 Simulator *SimulationThread::Sim() {return m_lpSim;}
71 
72 void SimulationThread::StartSimulation(std::string strSimFile, bool bForceNoWindows)
73 {
74  m_lpSim = Simulator::CreateSimulator(strSimFile, bForceNoWindows);
75 
76  //Set the most recently created simulation to be the active one.
77  ActiveSim(m_lpSim);
78 
79  m_lpSim->Load();
80  m_lpSim->VisualSelectionMode(SIMULATION_SELECTION_MODE);
81  m_lpSim->SimCallBack(this);
82  m_lpSim->PauseSimulation();
83 
84  m_SimThread = boost::thread(&SimulationThread::ProcessSimulation, this);
85 
86  //If we want to block till the sim is over then lets wait here until we get the notification that it has
87  //gone past the set simulation time and then stop the simulation.
88  boost::posix_time::ptime pt = boost::posix_time::microsec_clock::universal_time() + boost::posix_time::seconds(10);
89 
90  boost::interprocess::scoped_lock<boost::interprocess::interprocess_mutex> lock(m_WaitForInitEndMutex);
91  bool bWaitRet = m_WaitForInitEndCond.timed_wait(lock, pt);
92 
93  if(!bWaitRet)
94  THROW_PARAM_ERROR(Al_Err_lTimedOutWaitingForSimToStop, Al_Err_strTimedOutWaitingForSimToStop, "Sim ID", m_lpSim->ID());
95 
96  //Give it just smidge of time to start processing in sumulation loop. This is not strictly necessary, but I wanted to give it the time anyway.
97  boost::this_thread::sleep(boost::posix_time::milliseconds(100));
98 }
99 
100 void SimulationThread::ProcessSimulation()
101 {
102  try
103  {
104  m_bThreadProcessing = true;
105 
106  if(m_lpSim)
107  {
108  m_lpSim->Initialize();
109 
110  m_WaitForInitEndCond.notify_all();
111  m_lpSim->Simulate();
112  }
113  }
114  catch(CStdErrorInfo oError)
115  {
116  m_bThreadProcessing = false;
117  }
118  catch(...)
119  {
120  m_bThreadProcessing = false;
121  }
122 
123  m_bThreadProcessing = false;
124 }
125 
126 void SimulationThread::Simulate(float fltTime, bool bBlocking, float fltWaitTime)
127 {
128  if(m_lpSim && m_lpSim->Paused())
129  {
130  if(fltTime > 0)
131  m_lpSim->EndSimTime(fltTime);
132  else
133  m_lpSim->EndSimTime(-1);
134 
135  if(m_lpSim->SimRunning())
136  m_lpSim->ToggleSimulation();
137  else
138  m_lpSim->StartSimulation();
139  }
140 
141  if(bBlocking && fltTime > 0)
142  {
143  if(fltWaitTime <= 0)
144  fltWaitTime = fltTime+120;
145 
146  //If we want to block till the sim is over then lets wait here until we get the notification that it has
147  //gone past the set simulation time and then stop the simulation.
148  boost::posix_time::ptime pt = boost::posix_time::microsec_clock::universal_time() + boost::posix_time::seconds(fltWaitTime);
149 
150  boost::interprocess::scoped_lock<boost::interprocess::interprocess_mutex> lock(m_WaitForSimEndMutex);
151  bool bWaitRet = m_WaitForSimEndCond.timed_wait(lock, pt);
152 
153  StopSimulation();
154 
155  if(!bWaitRet)
156  THROW_PARAM_ERROR(Al_Err_lTimedOutWaitingForSimToStop, Al_Err_strTimedOutWaitingForSimToStop, "Sim ID", m_lpSim->ID());
157  }
158 }
159 
160 void SimulationThread::PauseSimulation()
161 {
162  if(m_lpSim)
163  m_lpSim->PauseSimulation();
164 }
165 
166 void SimulationThread::ResumeSimulation()
167 {
168  if(m_lpSim && m_lpSim->Paused())
169  m_lpSim->ToggleSimulation();
170 }
171 
172 void SimulationThread::ResetSimulation()
173 {
174  if(m_lpSim->Paused())
175  m_lpSim->ResetSimulation();
176  else
177  StopSimulation();
178 }
179 
180 void SimulationThread::StopSimulation()
181 {
182  if(m_lpSim)
183  {
184  m_lpSim->PauseSimulation();
185 
186  if(m_lpSim->WaitForSimulationBlock())
187  {
188  m_lpSim->ResetSimulation();
189  m_lpSim->UnblockSimulation();
190  }
191  else
192  THROW_PARAM_ERROR(Al_Err_lTimedOutWaitingForSimToStop, Al_Err_strTimedOutWaitingForSimToStop, "SimID", m_lpSim->ID());
193  }
194 }
195 
196 void SimulationThread::ShutdownSimulation()
197 {
198  if(m_bThreadProcessing)
199  {
200  if(m_lpSim)
201  m_lpSim->ShutdownSimulation();
202 
203  bool bTryJoin = false;
204 #if (BOOST_VERSION >= 105000)
205  bTryJoin = m_SimThread.try_join_for(boost::chrono::seconds(10));
206 #else
207  m_SimThread.join();
208 #endif
209  //if(m_lpSim)
210  //{
211  // delete m_lpSim;
212  // m_lpSim = NULL;
213  //}
214  }
215 }
216 
218 {
219  m_WaitForSimEndCond.notify_all();
220 }
221 
223 {
224  std::cout << "Critical error has occured. Shutting down the simulation.\r\n";
225  std::cout << strError << "\r\n";
226  ShutdownSimulation();
227 }
228 
229 void SimulationThread::HandleCriticalError(std::string strError)
230 {
231  std::cout << "Critical error has occured. Shutting down the simulation.\r\n";
232  std::cout << strError << "\r\n";
233  ShutdownSimulation();
234 }
235 
236 
237 
238 }
virtual void HandleCriticalError(std::string strError)
Handle critical-errors in the GUI. A critical error will report the error and then shut the entire ap...
Base class file for all Animat simulation objects.
virtual void HandleNonCriticalError(std::string strError)
Handle a non-critical error in the GUI. Non-critical errors are simply reported and the simulation st...
Declares the nervous system class.
Declares the simulation recorder class.
Declares the Robot IO control interface base class.
Simulates the entire environment.
Definition: Simulator.h:31
Root namespace for the base simulation library for AnimatLab.
Declares the body part class.
virtual bool Paused()
Gets whether the Simulation is paused.
Definition: Simulator.cpp:347
Information about the standard error.
Definition: StdErrorInfo.h:19
virtual std::string ID()
Gets the unique GUID ID of this object.
Definition: AnimatBase.cpp:167
virtual bool WaitForSimulationBlock(long lTimeout=6000)
Wait for simulation block.
Definition: Simulator.cpp:2079
virtual bool PauseSimulation()=0
Pauses the simulation.
static Simulator * CreateSimulator(std::string strAnimatModule, std::string strSimulationFile, bool bForceNoWindows=false)
Creates a simulator from a simulator file.
Definition: Simulator.cpp:3604
Declares the key frame class.
Declares the joint class.
Declares the organism class.
virtual bool SimRunning()
Gets whether the simulation is running.
Definition: Simulator.cpp:673
virtual int VisualSelectionMode()
Gets the visual selection mode.
Definition: Simulator.cpp:460
Declares a light object.
virtual bool StartSimulation()=0
Starts the simulation.
Declares the activated item class.
Declares a light manager object.
Declares the bounding box class.
virtual void Simulate()
Simulates the system.
Definition: Simulator.cpp:2680
Declares the node class.
virtual void NeedToStopSimulation()
Callback to inform that GUI that the currently running simulation needs to be stopped.
virtual void ResetSimulation()
Resets the the simulation to its orginal settings at time 0.
Definition: Simulator.cpp:2304
virtual void ToggleSimulation()=0
Toggles the simulation between running and paused.
void Std_TraceMsg(const int iLevel, std::string strMessage, std::string strSourceFile, int iSourceLine, bool bLogToFile, bool bPrintHeader)
Traces a message to the debugger window.
virtual void Load(std::string strFileName="")
Loads the simulation from an xml configuration file.
Definition: Simulator.cpp:2933
virtual void SimCallBack(ISimGUICallback *lpCallback)
Sets the calback object from the simulation.
Definition: Simulator.cpp:537
virtual void Initialize(int argc, const char **argv)=0
Initializes this object.
Declares the data chart manager class.
virtual void ShutdownSimulation()=0
Shuts down the simulation.
Declares the rigid body class.
Declares the structure class.
Declares the odor type class.
Declares the robotics inerface for animatlab.
Declares the odor class.
Declares the simulator class.
Declares the neural module class.
Declares the activated item manager class.
Declares the contact sensor class.
Declares the external stimuli manager class.
virtual void UnblockSimulation()
Unblock simulation.
Definition: Simulator.cpp:2048
Declares the receptive field class.
virtual float EndSimTime()
Gets the time at which to automatically end the simulation.
Definition: Simulator.cpp:982