AnimatLab  2
Test
PulsedLinkage.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 "Gain.h"
12 #include "BoundingBox.h"
13 #include "MovableItem.h"
14 #include "BodyPart.h"
15 #include "Joint.h"
16 #include "ReceptiveField.h"
17 #include "ContactSensor.h"
18 #include "RigidBody.h"
19 #include "Structure.h"
20 #include "NeuralModule.h"
21 #include "Adapter.h"
22 #include "NervousSystem.h"
23 #include "Organism.h"
24 #include "ActivatedItem.h"
25 #include "ActivatedItemMgr.h"
26 #include "DataChartMgr.h"
27 #include "ExternalStimuliMgr.h"
28 #include "KeyFrame.h"
29 #include "SimulationRecorder.h"
30 #include "OdorType.h"
31 #include "Odor.h"
32 #include "Light.h"
33 #include "LightManager.h"
34 #include "Simulator.h"
35 
36 #include "RobotInterface.h"
37 #include "RobotIOControl.h"
38 #include "RemoteControlLinkage.h"
39 #include "PulsedLinkage.h"
40 #include "RemoteControl.h"
41 
42 namespace AnimatSim
43 {
44  namespace Robotics
45  {
46 
47 PulsedLinkage::PulsedLinkage(void)
48 {
49  m_iMatchValue = 0;
52  m_iMatches = 0;
54  m_bMatchOnChange = true;
55  m_iPrevValue = 0;
56  m_aryPulses.clear();
57 }
58 
59 PulsedLinkage::~PulsedLinkage(void)
60 {
61 try
62 {
63  m_aryPulses.clear();
64 }
65 catch(...)
66 {Std_TraceMsg(0, "Caught Error in desctructor of PulsedLinkage\r\n", "", -1, false, true);}
67 }
68 
69 void PulsedLinkage::MatchValue(int iVal) {m_iMatchValue = iVal;}
70 
71 int PulsedLinkage::MatchValue() {return m_iMatchValue;}
72 
73 void PulsedLinkage::MatchOnChange(bool bVal) {m_bMatchOnChange = bVal;}
74 
75 bool PulsedLinkage::MatchOnChange() {return m_bMatchOnChange;}
76 
77 void PulsedLinkage::PulseDuration(float fltVal)
78 {
79  Std_IsAboveMin((float) 0, fltVal, true, "PulseDuration");
80  m_fltPulseDuration = fltVal;
81 }
82 
83 float PulsedLinkage::PulseDuration() {return m_fltPulseDuration;}
84 
85 void PulsedLinkage::PulseCurrent(float fltVal)
86 {
87  Std_IsAboveMin((float) 0, fltVal, true, "PulseCurrent");
88  m_fltPulseCurrent = fltVal;
89 }
90 
91 float PulsedLinkage::PulseCurrent() {return m_fltPulseCurrent;}
92 
93 float *PulsedLinkage::GetDataPointer(const std::string &strDataType)
94 {
95  std::string strType = Std_CheckString(strDataType);
96 
97  if(strType == "MATCHES")
98  return &m_fltMatchesReport;
99 
101 }
102 
103 bool PulsedLinkage::SetData(const std::string &strDataType, const std::string &strValue, bool bThrowError)
104 {
105  std::string strType = Std_CheckString(strDataType);
106 
107  if(RemoteControlLinkage::SetData(strType, strValue, false))
108  return true;
109 
110  if(strType == "MATCHVALUE")
111  {
112  MatchValue(atoi(strValue.c_str()));
113  return true;
114  }
115  else if(strType == "PULSEDURATION")
116  {
117  PulseDuration(atof(strValue.c_str()));
118  return true;
119  }
120  else if(strType == "PULSECURRENT")
121  {
122  PulseCurrent(atof(strValue.c_str()));
123  return true;
124  }
125  else if(strType == "MATCHONCHANGE")
126  {
127  MatchOnChange(Std_ToBool(strValue));
128  return true;
129  }
130 
131  //If it was not one of those above then we have a problem.
132  if(bThrowError)
133  THROW_PARAM_ERROR(Al_Err_lInvalidDataType, Al_Err_strInvalidDataType, "Data Type", strDataType);
134 
135  return false;
136 }
137 
138 void PulsedLinkage::QueryProperties(CStdPtrArray<TypeProperty> &aryProperties)
139 {
141  aryProperties.Add(new TypeProperty("MatchValue", AnimatPropertyType::Integer, AnimatPropertyDirection::Set));
142  aryProperties.Add(new TypeProperty("PulseDuration", AnimatPropertyType::Float, AnimatPropertyDirection::Set));
143  aryProperties.Add(new TypeProperty("PulseCurrent", AnimatPropertyType::Float, AnimatPropertyDirection::Set));
144  aryProperties.Add(new TypeProperty("MatchOnChange", AnimatPropertyType::Boolean, AnimatPropertyDirection::Set));
145 
146  aryProperties.Add(new TypeProperty("Matches", AnimatPropertyType::Integer, AnimatPropertyDirection::Get));
147 }
148 
149 #pragma endregion
150 
152 {
154  m_iMatches = 0;
155  m_aryPulses.clear();
156 }
157 
158 float PulsedLinkage::CalculateAppliedValue(float fltData)
159 {
160  float fltTotal = 0;
161  int iCount = m_aryPulses.size();
162  for(int iIdx=0; iIdx<iCount; iIdx++)
163  {
164  fltTotal += m_fltPulseCurrent;
165  m_aryPulses[iIdx] -= m_lpSim->PhysicsTimeStep();
166  }
167 
168  return fltTotal;
169 }
170 
171 void PulsedLinkage::CullPulses()
172 {
173  bool bDone = false;
174  while(!bDone)
175  {
176  int iCount = m_aryPulses.size();
177  int iDeleteID = -1;
178  for(int iIdx=0; iIdx<iCount && iDeleteID == -1; iIdx++)
179  if(m_aryPulses[iIdx] <= 0)
180  iDeleteID = iIdx;
181 
182  if(iDeleteID > -1)
183  {
184  //If we found one to delete then get rid of it.
185  m_aryPulses.RemoveAt(iDeleteID);
186 
188  //OutputDebugString("Pulse Culled\r\n");
189  }
190  else
191  bDone = true;
192  }
193 }
194 
195 void PulsedLinkage::IncrementMatches()
196 {
197  m_AccessMatchesMutex.lock();
198  m_iMatches++;
199  m_AccessMatchesMutex.unlock();
200 
202  //std::string strVal = "Matches: " + STR((int) m_iMatches) + "\r\n";
203  //OutputDebugString(strVal.c_str());
204 }
205 
207 {
208  if(m_bEnabled && !m_lpSim->Paused())
209  {
210  int iSource = (int) (*m_lpSourceData + (Std_Sign(*m_lpSourceData) * 0.5));
211 
212  if(m_bMatchOnChange && iSource != m_iPrevValue && iSource == m_iMatchValue)
213  IncrementMatches();
214  else if(!m_bMatchOnChange && iSource == m_iMatchValue)
215  IncrementMatches();
216 
217  m_iPrevValue = iSource;
218  }
219 }
220 
222 {
224  {
225  //Set the reporting value
227 
228  //If we have a match then add a new pulse
229  if(m_AccessMatchesMutex.try_lock())
230  {
231 
232  if(m_iMatches > 0)
233  {
234  //Limit to a total of 100 pulses active at any one time
235  if(m_aryPulses.size() < 100)
236  {
237  int iMatches = m_iMatches;
238  if(iMatches+m_aryPulses.size() > 100)
239  iMatches = 100 -m_aryPulses.size();
240 
241  for(int iIdx=0; iIdx<iMatches; iIdx++)
243  }
244 
245  //Reset matches for next time.
246  m_iMatches = 0;
247  }
248 
249  m_AccessMatchesMutex.unlock();
250  }
251 
252  ApplyValue(*m_lpSourceData);
253 
254  if(m_aryPulses.size() > 0)
255  CullPulses();
256  }
257 }
258 
259 void PulsedLinkage::Load(CStdXml &oXml)
260 {
261  RemoteControlLinkage::Load(oXml);
262 
263  oXml.IntoElem(); //Into Link Element
264 
265  MatchValue(oXml.GetChildInt("MatchValue", m_iMatchValue));
266  MatchOnChange(oXml.GetChildInt("MatchOnChange", m_bMatchOnChange));
267  PulseDuration(oXml.GetChildFloat("PulseDuration", m_fltPulseDuration));
268  PulseCurrent(oXml.GetChildFloat("PulseCurrent", m_fltPulseCurrent));
269 
270  oXml.OutOfElem(); //OutOf Link Element
271 }
272 
273 
274 
275  }
276 }
virtual void QueryProperties(CStdPtrArray< TypeProperty > &aryProperties)
Queries this object for a list of properties that can be changed using SetData.
Base class file for all Animat simulation objects.
Declares the nervous system class.
virtual void PhysicsTimeStep(float fltVal)
Sets the integration time step for the physics engine.
Definition: Simulator.cpp:1126
Declares the simulation recorder class.
Declares the Robot IO control interface base class.
float m_fltMatchesReport
Used to report up the number of matches.
Definition: PulsedLinkage.h:21
Root namespace for the base simulation library for AnimatLab.
int m_iMatches
Counts the number of matches found in StepIO to let the sim know.
Definition: PulsedLinkage.h:18
Declares the body part class.
bool m_bMatchOnChange
If true then it will only performa a match check when the value has changed.
Definition: PulsedLinkage.h:27
Simulator * m_lpSim
The pointer to a Simulation.
Definition: AnimatBase.h:43
float * m_lpTargetData
Pointer to the external value of the linked target.
virtual bool Paused()
Gets whether the Simulation is paused.
Definition: Simulator.cpp:347
virtual bool IntoElem()
Goes into the next element where the cursor is located.
Definition: StdXml.cpp:42
virtual bool SetData(const std::string &strDataType, const std::string &strValue, bool bThrowError=true)
Set a variable based on a string data type name.
Class that stores information about types for QueryProperty information.
Definition: TypeProperty.h:35
Declares the key frame class.
unsigned int m_iPrevValue
Keeps track of the previous source value for the change check.
Definition: PulsedLinkage.h:30
int Std_Sign(float fltVal)
Determines the sign of a number.
virtual void ResetSimulation()
Resets the simulation back to time 0.
Declares the joint class.
Declares the organism class.
virtual int GetChildInt(std::string strElementName)
Gets an integer value from the element with the specified name.
Definition: StdXml.cpp:456
bool Std_IsAboveMin(int iMinVal, int iVal, bool bThrowError, std::string strParamName, bool bInclusiveLimit)
Tests if a number is above a minimum value.
Declares a light object.
Declares the activated item class.
boost::interprocess::interprocess_mutex m_AccessMatchesMutex
mutex used to try and access matches variable.
Definition: PulsedLinkage.h:14
Declares a light manager object.
AnimatBase * m_lpTarget
Target object we are inserting into.
Declares the bounding box class.
Declares the gain base class.
virtual void StepIO()
This method is called from within the IO thread. It calls StepIO for each part.
float m_fltPulseCurrent
The amount of current to apply for a single pulse.
Definition: PulsedLinkage.h:36
float m_fltPulseDuration
The duration for which a single pulse should be applied.
Definition: PulsedLinkage.h:33
A standard xml manipulation class.
Definition: StdXml.h:19
Declares the node class.
bool Std_ToBool(int iVal)
Converts a value toa bool.
virtual void QueryProperties(CStdPtrArray< TypeProperty > &aryProperties)
Queries this object for a list of properties that can be changed using SetData.
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 float * GetDataPointer(const std::string &strDataType)
Returns a float pointer to a data item of interest in this object.
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 bool OutOfElem()
Goes out of the element where the cursor is located.
Definition: StdXml.cpp:56
float * m_lpSourceData
Pointer to the source data variable.
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.
virtual float * GetDataPointer(const std::string &strDataType)
Returns a float pointer to a data item of interest in this object.
Declares the structure class.
Declares the odor type class.
virtual void StepSimulation()
Step the simulation for this object.
virtual bool SetData(const std::string &strDataType, const std::string &strValue, bool bThrowError=true)
Set a variable based on a string data type name.
Declares the robotics inerface for animatlab.
int m_iMatchValue
The value we are trying to match in order to apply a pulse.
Definition: PulsedLinkage.h:24
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 ResetSimulation()
Resets the simulation back to time 0.
Declares the receptive field class.
virtual float GetChildFloat(std::string strElementName)
Gets a float value from the element with the specified name.
Definition: StdXml.cpp:617