AnimatLab  2
Test
ContactSensor.cpp
Go to the documentation of this file.
1 
7 #include "StdAfx.h"
8 #include "IMovableItemCallback.h"
9 #include "ISimGUICallback.h"
10 #include "AnimatBase.h"
11 
12 #include "Node.h"
13 #include "IPhysicsMovableItem.h"
14 #include "IPhysicsBody.h"
15 #include "BoundingBox.h"
16 #include "MovableItem.h"
17 #include "BodyPart.h"
18 #include "Joint.h"
19 #include "Gain.h"
20 #include "BellGain.h" //Need to remove later.
21 #include "ReceptiveField.h"
22 #include "ContactSensor.h"
23 #include "RigidBody.h"
24 #include "Structure.h"
25 #include "Organism.h"
26 #include "ActivatedItem.h"
27 #include "ActivatedItemMgr.h"
28 #include "DataChartMgr.h"
29 #include "ExternalStimuliMgr.h"
30 #include "KeyFrame.h"
31 #include "SimulationRecorder.h"
32 #include "OdorType.h"
33 #include "Odor.h"
34 #include "Light.h"
35 #include "LightManager.h"
36 #include "Simulator.h"
37 
38 namespace AnimatSim
39 {
40  namespace Environment
41  {
42 
50 {
51  m_lpFieldGain = NULL;
52  m_lpCurrentGain = NULL;
53  m_fltMaxForce = 100;
54 }
55 
63 {
64 
65 try
66 {
67  if(m_lpFieldGain)
68  delete m_lpFieldGain;
69 
70  if(m_lpCurrentGain)
71  delete m_lpCurrentGain;
72 
73  m_aryFields.RemoveAll();
74 }
75 catch(...)
76 {Std_TraceMsg(0, "Caught Error in desctructor of ContactSensor\r\n", "", -1, false, true);}
77 }
78 
88 
98 
111 {
112  Std_InValidRange((int) 0, (m_aryFields.GetSize()-1), iIndex, true, "Receptive Field Index");
113  return m_aryFields[iIndex];
114 }
115 
130 bool ContactSensor::FindReceptiveField(CStdPtrArray<ReceptiveField> &aryFields, float fltX, float fltY, float fltZ, int &iIndex)
131 {
132  int high = aryFields.GetSize(), low = -1, probe=0;
133 
134  while (high - low > 1)
135  {
136  probe = (high + low) / 2;
137  if (aryFields[probe]->GreaterThanThan(fltX, fltY, fltZ))
138  high = probe;
139  else
140  low = probe;
141  }
142 
143  if(low==-1)
144  iIndex = 0;
145  else
146  iIndex = high;
147 
148  if((probe < aryFields.GetSize() && aryFields[probe]->Equals(fltX, fltY, fltZ))
149  || (low > -1 && low < aryFields.GetSize() && aryFields[low]->Equals(fltX, fltY, fltZ))
150  || (high < aryFields.GetSize() && aryFields[high]->Equals(fltX, fltY, fltZ)))
151  return true;
152  else
153  return false;
154 }
155 
168 int ContactSensor::FindClosestReceptiveField(float fltX, float fltY, float fltZ)
169 {
170  int iSize = m_aryFields.GetSize(), iMinIndex = -1;
171  float fltDist = 0, fltMinDist = 0;
172  float fltXMin, fltYMin, fltZMin;
173 
174  ReceptiveField *lpField = NULL;
175  for(int iIndex=0; iIndex<iSize; iIndex++)
176  {
177  lpField = m_aryFields[iIndex];
178 
179  fltDist = sqrt( pow((fltX-lpField->m_vVertex[0]), 2) + pow((fltY-lpField->m_vVertex[1]), 2) + pow((fltZ-lpField->m_vVertex[2]), 2) );
180 
181  if(iMinIndex<0 || fltDist < fltMinDist)
182  {
183  fltMinDist = fltDist;
184  iMinIndex = iIndex;
185  fltXMin = lpField->m_vVertex[0]; fltYMin = lpField->m_vVertex[1]; fltZMin = lpField->m_vVertex[2];
186  }
187  }
188 
189  return iMinIndex;
190 }
191 
192 
206 bool ContactSensor::FindReceptiveField(float fltX, float fltY, float fltZ, int &iIndex)
207 {
208  return FindReceptiveField(m_aryFields, fltX, fltY, fltZ, iIndex);
209 }
210 
218 {
219  //DumpVertices(m_aryFields);
220 }
221 
230 void ContactSensor::DumpVertices(CStdPtrArray<ReceptiveField> &aryFields)
231 {
232  int iSize = aryFields.GetSize();
233  for(int iV=0; iV<iSize; iV++)
234  {
235  std::ostringstream oss;
236  aryFields[iV]->Trace(oss);
237  //oss << "\r\n";
238  Std_TraceMsg(StdLogDebug, oss.str(), "", -1, STD_TRACE_TO_FILE, false);
239  }
240 }
241 
242 void ContactSensor::AddReceptiveField(std::string strXml)
243 {
244  CStdXml oXml;
245  oXml.Deserialize(strXml);
246  oXml.FindElement("Root");
247  oXml.FindChildElement("ReceptiveField");
248 
249  LoadReceptiveField(oXml);
250 }
251 
252 void ContactSensor::RemoveReceptiveField(std::string strID, bool bThrowError)
253 {
254  int iPos = FindReceptiveFieldListPos(strID, bThrowError);
255  m_aryFields.RemoveAt(iPos);
256 }
257 
258 int ContactSensor::FindReceptiveFieldListPos(std::string strID, bool bThrowError)
259 {
260  std::string sID = Std_ToUpper(Std_Trim(strID));
261 
262  int iCount = m_aryFields.GetSize();
263  for(int iIndex=0; iIndex<iCount; iIndex++)
264  if(m_aryFields[iIndex]->ID() == sID)
265  return iIndex;
266 
267  if(bThrowError)
268  THROW_TEXT_ERROR(Al_Err_lReceptiveFieldIDNotFound, Al_Err_strReceptiveFieldIDNotFound, "ID");
269 
270  return -1;
271 }
272 
280 {
281  int iSize = m_aryFields.GetSize();
282  for(int iField=0; iField<iSize; iField++)
283  m_aryFields[iField]->m_fltCurrent = 0;
284 }
285 
299 void ContactSensor::ProcessContact(StdVector3 vPos, float fltForceMagnitude)
300 {
301  //if(fltForceMagnitude > m_fltMaxForce)
302  // fltForceMagnitude = m_fltMaxForce;
303 
304  float fltDist, fltFieldGain, fltForce, fltCurrent;
305  int iSize = m_aryFields.GetSize();
306  ReceptiveField *lpField = NULL;
307 
308  for(int iField=0; iField<iSize; iField++)
309  {
310  lpField = m_aryFields[iField];
311  fltDist = V3_DIST(lpField->m_vVertex, vPos) * m_lpSim->DistanceUnits();
312  fltFieldGain = m_lpFieldGain->CalculateGain(fltDist);
313  fltForce = fltForceMagnitude*fltFieldGain;
314  fltCurrent = m_lpCurrentGain->CalculateGain(fltForce);
315 
316  lpField->m_fltCurrent += fltCurrent;
317 
318  //if(fltCurrent > 1e-9)
319  // fltCurrent = fltCurrent;
320  }
321 }
322 
323 bool ContactSensor::AddItem(const std::string &strItemType, const std::string &strXml, bool bThrowError, bool bDoNotInit)
324 {
325  std::string strType = Std_CheckString(strItemType);
326 
327  if(strType == "RECEPTIVEFIELD")
328  {
329  AddReceptiveField(strXml);
330  return true;
331  }
332 
333  //If it was not one of those above then we have a problem.
334  if(bThrowError)
335  THROW_PARAM_ERROR(Al_Err_lInvalidItemType, Al_Err_strInvalidItemType, "Item Type", strItemType);
336 
337  return false;
338 }
339 
340 bool ContactSensor::RemoveItem(const std::string &strItemType, const std::string &strID, bool bThrowError)
341 {
342  std::string strType = Std_CheckString(strItemType);
343 
344  if(strType == "RECEPTIVEFIELD")
345  {
346  RemoveReceptiveField(strID);
347  return true;
348  }
349 
350  //If it was not one of those above then we have a problem.
351  if(bThrowError)
352  THROW_PARAM_ERROR(Al_Err_lInvalidItemType, Al_Err_strInvalidItemType, "Item Type", strItemType);
353 
354  return false;
355 }
356 
357 
358 void ContactSensor::Load(CStdXml &oXml)
359 {
360  AnimatBase::Load(oXml);
361 
362  oXml.IntoElem(); //Into Adapter Element
363 
364  oXml.IntoChildElement("FieldGain");
365  std::string strModuleName = oXml.GetChildString("ModuleName", "");
366  std::string strType = oXml.GetChildString("Type");
367  oXml.OutOfElem(); //OutOf Gain Element
368 
369  m_lpFieldGain = dynamic_cast<AnimatSim::Gains::Gain *>(m_lpSim->CreateObject(strModuleName, "Gain", strType));
370  if(!m_lpFieldGain)
371  THROW_TEXT_ERROR(Al_Err_lConvertingClassToType, Al_Err_strConvertingClassToType, "FieldGain");
372 
374  m_lpFieldGain->Load(oXml);
375 
376  oXml.IntoChildElement("CurrentGain");
377  strModuleName = oXml.GetChildString("ModuleName", "");
378  strType = oXml.GetChildString("Type");
379  oXml.OutOfElem(); //OutOf Gain Element
380 
381  m_lpCurrentGain = dynamic_cast<AnimatSim::Gains::Gain *>(m_lpSim->CreateObject(strModuleName, "Gain", strType));
382  if(!m_lpCurrentGain)
383  THROW_TEXT_ERROR(Al_Err_lConvertingClassToType, Al_Err_strConvertingClassToType, "FieldGain");
384 
386  m_lpCurrentGain->Load(oXml);
387 
390 
391  if(oXml.FindChildElement("Fields", false))
392  {
393  oXml.IntoElem(); //Into Fields Element
394  int iCount = oXml.NumberOfChildren();
395 
396  m_aryFields.RemoveAll();
397  for(int iIndex=0; iIndex<iCount; iIndex++)
398  {
399  oXml.FindChildByIndex(iIndex);
400  LoadReceptiveField(oXml);
401  }
402  oXml.OutOfElem(); //OutOf Fields Element
403  }
404 
405  oXml.OutOfElem(); //OutOf Adapter Element
406 }
407 
417 {
418  ReceptiveField *lpField = NULL;
419 
420  try
421  {
422  lpField = new ReceptiveField();
423  lpField->SetSystemPointers(m_lpSim, m_lpStructure, NULL, NULL, true);
424  lpField->Load(oXml);
425 
426  m_aryFields.Add(lpField);
427  }
428  catch(CStdErrorInfo oError)
429  {
430  if(lpField) delete lpField;
431  RELAY_ERROR(oError);
432  }
433  catch(...)
434  {
435  if(lpField) delete lpField;
436  THROW_ERROR(Std_Err_lUnspecifiedError, Std_Err_strUnspecifiedError);
437  }
438 }
439 
440  } //Environment
441 } //AnimatSim
virtual void Deserialize(std::string &strXml)
Deserializes a string into an xml document.
Definition: StdXml.cpp:162
Base class file for all Animat simulation objects.
Declares the simulation recorder class.
ContactSensor()
Default constructor.
virtual void SetSystemPointers(Simulator *lpSim, Structure *lpStructure, NeuralModule *lpModule, Node *lpNode, bool bVerify)
Sets the system pointers.
virtual bool FindChildElement(std::string strElementName, bool fThrowError=true)
Finds a child element by name.
Definition: StdXml.cpp:256
Root namespace for the base simulation library for AnimatLab.
float m_fltMaxForce
The maximum force force that we can use when calculating the current.
Definition: ContactSensor.h:38
Declares the bell gain class.
bool UseLimits()
Tells whether limits should be used.
Definition: Gain.cpp:87
Declares the body part class.
StdVector3 m_vVertex
The vertex of the center of the receptive field in global coordinates.
virtual bool FindElement(std::string strElementName, bool fThrowError=true)
Finds an element with the specified name.
Definition: StdXml.cpp:179
Simulator * m_lpSim
The pointer to a Simulation.
Definition: AnimatBase.h:43
void DumpVertices(CStdPtrArray< ReceptiveField > &aryFields)
Dumps the vertices to console.
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 IntoElem()
Goes into the next element where the cursor is located.
Definition: StdXml.cpp:42
Gain * FieldGain()
Gets the field Gain that modulates the contact force based on its distance from the center of the rec...
The Gain base class.
Definition: Gain.h:35
float UpperLimit()
Gets the upper limit.
Definition: Gain.cpp:131
virtual void DistanceUnits(std::string strUnits)
Sets the distance units.
Definition: Simulator.cpp:1717
Declares the key frame class.
bool Std_InValidRange(int iMinVal, int iMaxVal, int iVal, bool bThrowError, std::string strParamName)
Tests whether a number is within a valid range.
void ClearCurrents()
Clears the currents of ReceptiveFields.
Declares the joint class.
Declares the organism class.
int FindClosestReceptiveField(float fltX, float fltY, float fltZ)
Searches for the first closest receptive field.
AnimatSim::Environment::Structure * m_lpStructure
The pointer to this items parent Structure. If this is not relevant for this object then this is NULL...
Definition: AnimatBase.h:46
std::string Std_Trim(std::string strVal)
Trims a string.
Declares a light object.
Declares the activated item class.
virtual bool RemoveItem(const std::string &strItemType, const std::string &strID, bool bThrowError=true)
Removes a child item from this parent.
virtual CStdSerialize * CreateObject(std::string strModule, std::string strClassName, std::string strType, bool bThrowError=true)
Creates an object using a class factory.
Definition: Simulator.cpp:3440
Declares a light manager object.
Declares the bounding box class.
Declares the gain base class.
A standard xml manipulation class.
Definition: StdXml.h:19
void ProcessContact(StdVector3 vPos, float fltForceMagnitude)
Process a contact for all ReceptiveFields.
Gain * CurrentGain()
Gets the Gain that calculates the current to apply to associated neurons using the modulated force of...
Declares the node class.
float m_fltCurrent
The accumulated current for this receptive field.
virtual std::string GetChildString(std::string strElementName)
Gets a string value from the element with the specified name.
Definition: StdXml.cpp:307
virtual void Load(StdUtils::CStdXml &oXml)
Loads the item using an XML data packet.
Definition: AnimatBase.cpp:771
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 FindReceptiveField(CStdPtrArray< ReceptiveField > &aryFields, float fltX, float fltY, float fltZ, int &iIndex)
Searches for the first receptive field that is closes to the specified location.
virtual int NumberOfChildren()
Gets the number of children of the current element.
Definition: StdXml.cpp:202
void FinishedAddingVertices()
Called when we are finished adding vertices. This is used for debugging purposes. ...
Gain * m_lpFieldGain
The Gain function that modulates the force of contact based on the distance from the center of the Re...
Definition: ContactSensor.h:32
virtual bool OutOfElem()
Goes out of the element where the cursor is located.
Definition: StdXml.cpp:56
Declares the data chart manager class.
Declares the rigid body class.
virtual bool IntoChildElement(std::string strElementName, bool bThrowError=true)
Goes into the child element with the specified name.
Definition: StdXml.cpp:278
virtual float CalculateGain(float fltInput)=0
Calculates the gain.
std::string Std_CheckString(std::string strVal)
Converts a string to upper case and trims it.
Declares the structure class.
Declares the odor type class.
virtual bool AddItem(const std::string &strItemType, const std::string &strXml, bool bThrowError=true, bool bDoNotInit=false)
Adds a new object to this parent.
Declares the odor class.
Declares the simulator class.
virtual bool FindChildByIndex(int iIndex, bool bThrowError=true)
Finds a child element by index.
Definition: StdXml.cpp:225
std::string Std_ToUpper(std::string strVal)
Converts a string to upper case.
CStdPtrArray< ReceptiveField > m_aryFields
The array of ReceptiveField objects.
Definition: ContactSensor.h:29
Declares the activated item manager class.
Declares the contact sensor class.
Declares the external stimuli manager class.
Gain * m_lpCurrentGain
The Gain that calculates the amount of current to apply to any associated neurons based on the modula...
Definition: ContactSensor.h:35
Receptive field that generates current based on the amount of contact force, and how close it is to t...
Declares the receptive field class.
ReceptiveField * GetReceptiveField(int iIndex)
Gets a receptive field based on its index in the array.
void LoadReceptiveField(CStdXml &oXml)
Loads a receptive field.