AnimatLab  2
Test
ThreadedModule.cpp
Go to the documentation of this file.
1 
7 #include "StdAfx.h"
8 #include "IMovableItemCallback.h"
9 #include "ISimGUICallback.h"
10 #include "IMotorizedJoint.h"
11 #include "AnimatBase.h"
12 
13 #include "Node.h"
14 #include "Link.h"
15 #include "IPhysicsMovableItem.h"
16 #include "IPhysicsBody.h"
17 #include "BoundingBox.h"
18 #include "MovableItem.h"
19 #include "BodyPart.h"
20 #include "Joint.h"
21 #include "ReceptiveField.h"
22 #include "ContactSensor.h"
23 #include "RigidBody.h"
24 #include "Structure.h"
25 #include "NeuralModule.h"
26 #include "Adapter.h"
27 #include "NervousSystem.h"
28 #include "Organism.h"
29 #include "ActivatedItem.h"
30 #include "ActivatedItemMgr.h"
31 #include "DataChartMgr.h"
32 #include "ExternalStimuliMgr.h"
33 #include "KeyFrame.h"
34 #include "SimulationRecorder.h"
35 #include "OdorType.h"
36 #include "Odor.h"
37 #include "Light.h"
38 #include "LightManager.h"
39 #include "Simulator.h"
40 
41 #include "ThreadedModule.h"
42 
43 namespace AnimatSim
44 {
45  namespace Behavior
46  {
47 
55 {
56  m_bSetupStarted = false;
57  m_bSetupComplete = false; // flag so we setup when its ready, you don't need to touch this :)
58  m_bStopThread = false;
59  m_bThreadProcessing = false;
61  m_bPauseThread = false;
62  m_bThreadPaused = false;
64 }
65 
66 
74 {
75 try
76 {
78 }
79 catch(...)
80 {Std_TraceMsg(0, "Caught Error in desctructor of ThreadedModule\r\n", "", -1, false, true);}
81 }
82 
83 void ThreadedModule::PauseThread(bool bVal)
84 {
85  m_bPauseThread = bVal;
86  m_bThreadPaused = false;
87 }
88 
89 bool ThreadedModule::PauseThread() {return m_bPauseThread;}
90 
91 bool ThreadedModule::ThreadPaused() {return m_bThreadPaused;}
92 
102 
103 #pragma region DataAccesMethods
104 
105 float *ThreadedModule::GetDataPointer(const std::string &strDataType)
106 {
107  std::string strType = Std_CheckString(strDataType);
108 
109  if(strType == "STEPTHREADDURATION")
110  return &m_fltStepThreadDuration;
111  else
112  return NeuralModule::GetDataPointer(strDataType);
113 
114  return NULL;
115 }
116 
117 void ThreadedModule::QueryProperties(CStdPtrArray<TypeProperty> &aryProperties)
118 {
119  NeuralModule::QueryProperties(aryProperties);
120 
121  aryProperties.Add(new TypeProperty("StepThreadDuration", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
122 }
123 
124 #pragma endregion
125 
126 void ThreadedModule::StartThread()
127 {
128  int iWaitTime = 30;
129 #ifdef _DEBUG
130  iWaitTime = 200;
131 #endif
132 
133  //Reset key variables.
134  m_bSetupStarted = false;
135  m_bSetupComplete = false;
136  m_bStopThread = false;
137  m_bThreadProcessing = false;
139  m_bPauseThread = false;
140  m_bThreadPaused = false;
142 
143  boost::posix_time::ptime pt = boost::posix_time::microsec_clock::universal_time() + boost::posix_time::seconds(iWaitTime);
144 
145  boost::interprocess::scoped_lock<boost::interprocess::interprocess_mutex> lock(m_WaitForSetupMutex);
146 
148  m_Thread = boost::thread(&ThreadedModule::ProcessThread, this);
149 
150  std::cout << "Waiting for thread return\r\n";
152  bool bWaitRet = m_WaitForSetupCond.timed_wait(lock, pt);
153 
154  if(!bWaitRet)
155  {
156  std::cout << "Thread Timed out\r\n";
157  ShutdownThread();
158  THROW_ERROR(Al_Err_lErrorSettingUpIOThread, Al_Err_strErrorSettingUpIOThread);
159  }
160 
161  std::cout << "Thread returned\r\n";
162 }
163 
164 void ThreadedModule::WaitForThreadNotifyReady()
165 {
166  //Wait to fire the signal until we get notification that it is waiting.
168  boost::this_thread::sleep(boost::posix_time::microseconds(500));
169 }
170 
171 void ThreadedModule::ProcessThread()
172 {
173  try
174  {
175  m_bThreadProcessing = true;
176 
177  SetupThread();
178 
179  m_bSetupComplete = true;
180 
181  WaitForThreadNotifyReady();
182 
183  //Notify it back that we are ready.
184  m_WaitForSetupCond.notify_all();
185 
186  while(!m_bStopThread)
187  {
188  if(m_bPauseThread || m_lpSim->Paused())
189  {
190  m_bThreadPaused = true;
191  boost::this_thread::sleep(boost::posix_time::microseconds(1000));
192  }
193  else
194  {
195  m_bThreadPaused = false;
196  StepThread();
197  }
198  }
199  }
200  catch(CStdErrorInfo oError)
201  {
202  m_bThreadProcessing = false;
203  }
204  catch(...)
205  {
206  m_bThreadProcessing = false;
207  }
208 
209  m_bThreadProcessing = false;
210 }
211 
212 void ThreadedModule::ExitThread()
213 {
214  TRACE_DEBUG("ExitThread.");
215 
217  {
218  //Allow thread close calls.
219  CloseThread();
220 
221  //Tell the thread to shutdown
222  m_bStopThread = true;
223 
224  TRACE_DEBUG("Joint Thread.\r\n");
225 
226  bool bTryJoin = false;
227 #if (BOOST_VERSION >= 105000)
228  bTryJoin = m_Thread.try_join_for(boost::chrono::seconds(30));
229 #else
230  m_ioThread.join();
231 #endif
232  }
233 }
234 
247 {
248  //make sure we wait until the other thread is waiting before sending our completed signal
250  boost::this_thread::sleep(boost::posix_time::microseconds(1000));
251 }
252 
253 void ThreadedModule::CloseThread()
254 {
255 }
256 
265 {
266 }
267 
276 {
277  m_bThreadPaused = true;
278  while(m_bPauseThread)
279  boost::this_thread::sleep(boost::posix_time::microseconds(1000));
280  m_bThreadPaused = false;
281 }
282 
291 {
292  while(!m_bThreadPaused)
293  boost::this_thread::sleep(boost::posix_time::microseconds(1000));
294 }
295 
304 {
305  m_bPauseThread = true;
306 
307  if(!m_bEnabled || (m_lpSim->InSimulation() && m_lpSim->Paused()))
308  m_bThreadPaused = true;
309 
310  while(!m_bThreadPaused)
311  boost::this_thread::sleep(boost::posix_time::microseconds(1000));
312 }
313 
322 {
323  m_bPauseThread = false;
324 
325  if(!m_bEnabled || (m_lpSim->InSimulation() && m_lpSim->Paused()))
326  m_bThreadPaused = false;
327 
328  while(m_bThreadPaused)
329  boost::this_thread::sleep(boost::posix_time::microseconds(1000));
330 }
331 
341 {
342  //Prevent any more attempts to write to the comm channel.
344  {
345  StartPause();
346  WaitTillPaused();
347  }
348 
349  ExitThread();
350 }
351 
352  }
353 }
boost::thread m_Thread
Thread responsible for doing IO processing.
boost::interprocess::interprocess_condition m_WaitForSetupCond
Condition used to determine when the IO is setup.
Base class file for all Animat simulation objects.
Declares the nervous system class.
Declares the simulation recorder class.
virtual void StepThread()
This method is called from within the IO thread. It calls StepIO for each part.
bool m_bWaitingForThreadNotify
Used to signal to the IO thread that we are waiting for their return signal.
virtual bool InSimulation()
Used to determine if we are running in a simulation, or in a real control mode.
Definition: Simulator.cpp:1673
Root namespace for the base simulation library for AnimatLab.
Declares the body part class.
virtual void QueryProperties(CStdPtrArray< TypeProperty > &aryProperties)
Queries this object for a list of properties that can be changed using SetData.
Simulator * m_lpSim
The pointer to a Simulation.
Definition: AnimatBase.h:43
virtual bool Paused()
Gets whether the Simulation is paused.
Definition: Simulator.cpp:347
Information about the standard error.
Definition: StdErrorInfo.h:19
Class that stores information about types for QueryProperty information.
Definition: TypeProperty.h:35
bool m_bPauseThread
Set to true to pause the thread processing. Set back to false to resume it.
Declares the key frame class.
Declares the joint class.
Declares the organism class.
virtual void ExitPause()
This method is waits until the m_bIOPaused flag is set back to false.
ThreadedModule(void)
Default constructor.
Declares a light object.
virtual float StepThreadDuration()
Gets the time duration required to perform one step of the thread for all parts in this control...
virtual void StartPause()
This method is waits until the m_bIOPaused flag is set to true.
Declares the activated item class.
Declares a light manager object.
Declares the bounding box class.
virtual ~ThreadedModule(void)
Destructor.
bool m_bSetupStarted
Set to true once the thread begins its setup.
Declares the node class.
virtual void QueryProperties(CStdPtrArray< TypeProperty > &aryProperties)
Queries this object for a list of properties that can be changed using SetData.
Definition: AnimatBase.cpp:447
virtual void WaitWhilePaused()
This method is waits until the m_bPauseIO flag is set back to false.
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.
bool m_bThreadProcessing
True while the io thread processing loop is going on.
virtual void SetupThread()
This method is called after all connections to whatever control board have been made. It calls each parts SetupIO method. For example, We connect to a Firmata microcontroller like an Arduino, and then do a setup that could take some time. We should not attempt to setup any of the pins until after the board itself has been setup. After that we need to loop through and setup all the parts.
bool m_bEnabled
Tells if this item is enabled or not. If it is not enabled then it is not run.
Definition: AnimatBase.h:40
virtual float * GetDataPointer(const std::string &strDataType)
Returns a float pointer to a data item of interest in this object.
bool m_bStopThread
Flags the thread processing loop to exit.
Declares the data chart manager class.
Declares the rigid body class.
std::string Std_CheckString(std::string strVal)
Converts a string to upper case and trims it.
boost::interprocess::interprocess_mutex m_WaitForSetupMutex
Mutex responsible for waiting until the IO is finished setting up.
Declares the structure class.
bool m_bSetupComplete
Set to true once the thread is setup correctly.
Declares the odor type class.
bool m_bThreadPaused
Is set to true once the thread loop is paused.
Declares the odor class.
Declares the simulator class.
Declares the neural module class.
float m_fltStepThreadDuration
The time it takes to perform a step of the IO for all parts in this control.
Declares the activated item manager class.
Declares the contact sensor class.
Declares the external stimuli manager class.
virtual void WaitTillPaused()
This method is waits until the m_bIOPaused flag is set to true.
Declares the receptive field class.
virtual float * GetDataPointer(const std::string &strDataType)
Returns a float pointer to a data item of interest in this object.
virtual void ShutdownThread()
This method is called just before the IO thread is closed down. It gives the IO objects a chance to d...